ST_IntersectsとLINESTRINGの縮退


9

PostGISには、(極を表す)LINESTRING Zオブジェクトの束があり、(POLYGONによって表される)エリア内にあるものを見つけたいと思います。この演習では、ポールがほぼ垂直であると想定して、エリアの境界と交差しないようにします。

問題は、ポールが正確に垂直になることがあるということです。

私がしたいこのクエリは成功しません:

SELECT ST_Intersects(ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));

いくつかの亜種を調査して、これは成功します:

SELECT ST_Intersects(ST_GeomFromText('POINT (544483.525 6849134.28)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));

これは成功しません:

SELECT ST_Intersects(ST_GeomFromText('LINESTRING (544483.525 6849134.28,544483.525 6849134.28)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));

3DIntersectsクエリを実行すると、成功します。

SELECT ST_3DIntersects(ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356),
ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356));

ただし、次のことを通知します。

One or both of the geometries is missing z-value. The unknown z-value will be regarded as "any value"

つまり、これはうまくいきますが、ログがノイズでいっぱいになり、警告をオフにしたくないのです。

OpenGIS Simple Feature Access Standard(パート1、セクション4.14を参照)を読んだところ、LINESTRINGは縮退したものですが、トポロジ的に閉じていると解釈されるため、交差するはずです。

これは正しいです?

編集

いくつかの実験の後、私は自分の質問の一部に答えることができます。上記のクエリがfalseを返すのは、LINESTRING Zが有効ではないと考えられているためです。

SELECT ST_IsValidReason(ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356));
                           st_isvalidreason                           
----------------------------------------------------------------------
 Too few points in geometry component[544483.525 6849134.28 104.1098]
(1 row)

これは、OGCが3Dをサポートしていないため、GDAL / PostGISが3Dをサポートするのは一種の礼儀正しい方法です。

対応するLINESTRINGが無効であることを示すOGC仕様にはまだ何も見つかりませんが、それを受け入れることができます。

だから私は本当に質問だと思います:常に有効な2Dジオメトリを返す3Dジオメトリの一部のフットプリントを公式に祝福する方法はありますか?

回答:


6

最初のクエリの本当に簡単な修正は、ST_MakeValidを使用して「有効な」ジオメトリを作成し、trueを返すことです。

SELECT ST_Intersects(ST_MakeValid(A), B), ST_AsText(ST_MakeValid(A)) AS ST_MakeValid
FROM (
  SELECT ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356) AS A,
         ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356) AS B
) AS d;

-[ RECORD 1 ]-+-----------------------------------------
st_intersects | t
st_makevalid  | POINT Z (544483.525 6849134.28 104.1098)

ST_IsValidまたはST_IsValidReasonによって検出されたように、LineStringオブジェクトが無効だったため、元のクエリは失敗しました。これは、ST_Intersectsが2D演算子であるため、ジオメトリが強制的に2次元になりLINESTRING(544483.525 6849134.28,544483.525 6849134.28)、これは無効です。

ST_MakeValidは、(2D空間で)繰り返される座標を削除し、結果のジオメトリには座標が1つしかないため、ポイントタイプに変更します。

Z座標がまだ残っていることがわかりますが、無視されます。これが気になる場合は、ST_Force2Dを使用して、ST_Intersectsなどの 2Dジオメトリを使用することもできます。

SELECT ST_Intersects(ST_MakeValid(ST_Force2D(A)), B),
  ST_AsText(ST_Force2D(A)) AS ST_Force2D,
  ST_AsText(ST_MakeValid(ST_Force2D(A))) AS ST_MakeValid
FROM (
  SELECT ST_GeomFromText('LINESTRING Z (544483.525 6849134.28 104.1098,544483.525 6849134.28 114.6)',28356) AS A,
         ST_GeomFromText('POLYGON((543907.636214323 6848710.84802846,543909.787417164 6849286.92923919,544869.040437688 6849283.30837091,544866.842236582 6848707.22673193,543907.636214323 6848710.84802846))',28356) AS B
) AS d;

-[ RECORD 1 ]-+--------------------------------------------------------
st_intersects | t
st_force2d    | LINESTRING(544483.525 6849134.28,544483.525 6849134.28)
st_makevalid  | POINT(544483.525 6849134.28)

ありがとう!これは何が起こっているのかについての良い説明であり、回避策もまた良いです。
仮名
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.