ポリゴンのPostGIS ST_Intersectionはラインを返すことができます


9

あるテーブルのポリゴンを別のテーブルのポリゴンでクリップすると、ST_Intersectionは、ST_Dumpで処理できる結果のセットを返すことができます。返される複数のジオメトリは、必ずしもST_Polygonではなく、ST_LineString(おそらくポイント)でもあります。したがって、クエリを実行すると

INSERT INTO c (geom)
  (SELECT (ST_Dump(ST_Intersection(a.geom,b.geom))).geom
  FROM a INNER JOIN b ON ST_Intersects(a.geom, b.geom));

テーブル "c"にクリップされたポリゴンを入力しようとすると、次のエラーで失敗します:ジオメトリタイプ(LineString)が列タイプ(ポリゴン)と一致しません

別のネストされたSELECTステートメントを実行して、ポリゴンジオメトリのみが通過するようにしました。

INSERT INTO c (geom)
  (SELECT geom FROM
    (SELECT (ST_Dump(ST_Intersection(a.geom,b.geom))).geom
    FROM a INNER JOIN b ON ST_Intersects(a.geom, b.geom))) AS cl
    WHERE ST_GeometryType(cl.geom)='ST_Polygon');

これは少し面倒なので、無効なジオメトリを削除するためのよりエレガントなソリューションがあるかどうか疑問に思いますか?


ところで、私はコードブロックの前に<!-言語:lang-sql->を置きましたが、まだハイライティングはありません。初心者のためのヒントはありますか?
RobertŠpendl2014年

コードをフォーマットするには、単純に貼り付けて選択し{}、質問編集ウィンドウの上にある[コードサンプル]ボタンを使用します。
PolyGeo

ええ、私はそうしました、コードは「コード」としてマークされていますが、キーワードはまだ色付けされていません。
RobertŠpendl2014年

私は通常、ここでSQLコードを美化しようとはしませんが、meta.stackexchange.com / questions / 90521 /…で役立つように見えるメタ投稿を見つけました-「コメントとコードの間に空白行」を残しましたか?
PolyGeo

2つのジオメトリの交差により、あらゆるタイプのジオメトリが生成される可能性があるため、現在の解決策が最も直接的であると思います。
マイクT

回答:


9

これは、SQL言語関数を使用するのに適した場所です。この状況で機能する簡単なものを次に示します。

CREATE OR REPLACE FUNCTION PolygonalIntersection(a geometry, b geometry)
RETURNS geometry AS $$
SELECT ST_Collect(geom)
FROM 
(SELECT (ST_Dump(ST_Intersection(a, b))).geom 
UNION ALL
-- union in an empty polygon so we get an 
-- empty geometry instead of NULL if there
-- is are no polygons in the intersection
SELECT ST_GeomFromText('POLYGON EMPTY')) SQ
WHERE ST_GeometryType(geom) = 'ST_Polygon';
$$ LANGUAGE SQL;

これにより、交差のポリゴンコンポーネントは保持されますが、その他はすべて破棄されます。コンポーネントがある場合やない場合でも、常にMultiPolygonを返します。

WITH 
      square   as (SELECT ST_GeomFromText('POLYGON ((0 0, 0  1,  1  1,  1  0, 0 0))') AS geom),
biggersquare   as (SELECT ST_GeomFromText('POLYGON ((0 0, 0 10, 10 10, 10  0, 0 0))') AS geom),
adjacentsquare as (SELECT ST_GeomFromText('POLYGON ((0 0, 1  0,  1 -1, -1 -1, 0 0))') AS geom)   

SELECT ST_AsText(PolygonalIntersection(square.geom, biggersquare.geom))
  FROM square, biggersquare;
--"MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)))"

SELECT ST_AsText(PolygonalIntersection(square.geom, adjacentsquare.geom))
  FROM square, adjacentsquare;
--"MULTIPOLYGON(EMPTY)"

3

@dbastonからの非常に良い答え。ただし、nullではなく空のジオメトリを返すと、返される空のジオメトリにsridがないため、問題が発生する可能性があります。St_IntersectionはMultiPolygonも返す場合があります。この更新された機能は私にとって本当に役に立ちました:

CREATE OR REPLACE FUNCTION PolygonalIntersection(a geometry, b geometry)
RETURNS geometry AS $$
SELECT ST_Collect(geom)
FROM 
(SELECT (ST_Dump(ST_Intersection(a, b))).geom 
) SQ
WHERE ST_GeometryType(geom) = 'ST_Polygon' OR ST_GeometryType(geom) = 'ST_MultiPolygon';
$$ LANGUAGE SQL;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.