PostGISでジオメトリをクリーニングしますか?


12

非常に大きなポリゴンレイヤーで処理を実行しようとしています。ただし、次のようなさまざまなジオメトリエラーが発生しています。

NOTICE:  Ring Self-intersection at or near point 470396.52017068537 141300.52235257279
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 504154.61769969884 140782.04115761846
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 505255.50242871145 140803.34860398644
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 510312.46970004693 141215.29256710084
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 510312.46970004693 141215.29256710084
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 511839.50335641927 141115.85781738357
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 515064.03024010791 140895.68087158105
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 519233.18724611058 140881.47590733573
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 521072.73011588014 141044.83299615697
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 523331.31943088671 141144.26774587421
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 523331.31943088671 141144.26774587424
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 523395.24176999065 140725.22130063715
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 524531.63890961662 140810.45108610913
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1

私はここで提案された機能を試しました:https : //trac.osgeo.org/postgis/wiki/UsersWikiCleanPolygons

ジオメトリをクリーニングするために、私が使用したコードは次のとおりです:

UPDATE public.mytable
SET geom=cleangeometry(geom);

その結果:

ERROR:  GEOSisSimple: IllegalArgumentException: This method does not support GeometryCollection arguments

そしてまた

UPDATE public.valid_mytable
SET geom=ST_MakeValid(geom);

これは機能しますが、最初にジオメトリ列をジオメトリに変更した場合のみ

ALTER TABLE public.mytable  ALTER COLUMN geom SET DATA TYPE geometry;

これにより、他の関数では動作しないテーブルが残ります。

ERROR:  Relate Operation called with a LWGEOMCOLLECTION type.  This is unsupported.

列をジオメトリ(MultiPolygon)に戻してみました

ALTER TABLE public.my_table ALTER COLUMN geom SET DATA TYPE geometry(MultiPolygon);

しかし、これは失敗します

ERROR:  Geometry type (GeometryCollection) does not match column type (MultiPolygon)

PostGIS in Action(Second Ed)http://www.manning.com/obe/を試してみましたが、無効なジオメトリを検出するための関数しか見つけることができませんが、データセットが大きすぎて手動で修正できません。それらを自動的に修正する何かが必要です。


ST_MakeValid()を実行してみると、問題のあるポリゴンを分離することができました。結果は次のとおりです。

ERROR:  Geometry type (GeometryCollection) does not match column type      (MultiPolygon)
 ********** Error **********

 ERROR: Geometry type (GeometryCollection) does not match column type      (MultiPolygon)
SQL state: 22023

ジオメトリ列のタイプチェックを行ったところ、タイプは「マルチポリゴン」であると表示されました


ST_MakeValidは可能な限り修正します。
user30184

わかりました。ありがとうございます。私の質問で実際に間違いを犯しましたが、列に問題を引き起こすのはST_Make_Validであると言及するのを忘れていました。ST_MakeValidを使用しましたが、動作させるにはgeom列をgeometryデータ型に変更する必要があります。一度実行すると、geometry(MultiPolygon)に戻すことができません
Mart

2
多くの無効なジオメトリを処理するハックST_Buffer(geom、0)を使用できます。ST_MakeValidを使用することもできます。最後に、新しいテーブルを選択して、where句にST_IsValid(geom)を配置してみます。
John Powell

おかげで、私はすでにバッファハックを試しましたが、うまくいきませんでした。ジオメトリ(MultiPolygon)ではなく、ジオメトリ入力が必要でした。有効なポリゴンのみを選択して、フィルターで除外される数を確認します。
2015

1
OK。これは、GeometryCollectionを生成するポリゴンとともに、st_makevalid生成ポイントとLineStringに由来します。これに対する修正があり、数時間で説明します。私はサーフィンに行きます:-)
ジョン・パウエル

回答:


15

あなただけのポリゴンまたはマルチポリゴンたい場合ST_MakeValidを、あなたは使用することができますST_Dumpを構成するジオメトリを抽出して、ジオメトリタイプのためにテストします。ST_MakeValidは、GeometryCollectionの取得元であるポイントまたはラインストリングを生成する場合があります。次のようなものを試してください:

SELECT 
  g.geom, 
  row_number() over() AS gid,
FROM 
  (SELECT 
     (ST_DUMP(ST_MakeValid (geom))).geom FROM your_table
  ) AS g
WHERE ST_GeometryType(g.geom) = 'ST_MultiPolygon' 
   OR ST_GeometryType(g.geom) = 'ST_Polygon';

OR条件の代わりにIN句を使用できますが、結果とクエリプランは同じです。マルチポリゴンのみが必要な場合は、ST_DumpST_Multi関数でラップできます。

row_number()over()は、ST_Dumpから返されたジオメトリごとに、1から始まる一意のIDを返します。ST_Dumpから返されたパス要素を使用しても、同じ結果が得られます。

ST_MakeValidは一般に(または常に)出力から出力への1対1のマッピングを生成するため、直接更新が機能する可能性は低いため、これをCREATE TABLE clean_geoms AS SELECT .... typeステートメントと組み合わせるとよいでしょう。

現在、私には手段がないため、これはテストされていません。したがって、括弧が間違っている可能性がありますが、一般的な原則は健全です。お役に立てれば。


19

ST_CollectionExtractを試して、GeometryCollectionsから[Multi] Polygonsを抽出できます。ST_Multiを使用して、それらをMuliPolygonとして強制します。

UPDATE public.valid_lcmsouthshapefile
  SET geom=ST_Multi(ST_CollectionExtract(ST_MakeValid(geom), 3))
  WHERE NOT ST_IsValid(geom);

完了したら、CHECK制約を使用して、それらが有効であることを確認します。詳細はこちら

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