waigani's diary

QGISを中心にFOSS4Gをいじくる

PostGIS 2.0のST_MakeValid

"PostGIS 2.0 New Features: ST_MakeValid"が流れてきたので、これはやってみねばとPostGIS 2.0の新機能に初挑戦してみました。
ST_isvalid()でfalseと判断される図形に悩まされていた方には朗報、validな図形に直してくれるのかもしれません。

使った環境

binaryがあるなら使います。windowsのbainaryを拝借してきました。

この組み合わせで行っています。

まずは紹介されていた図形で試す

Paul Ramsey さんのfavorite invalid polygon はfigure-eight(ねじれたやつですか)みたいですね。
テストのためのテーブルを作って、insertしてみます。

CREATE TABLE test (
  gid SERIAL PRIMARY KEY,
  geom GEOMETRY(POLYGON, -1)
);
insert into test(geom)
values(st_polygonfromtext('POLYGON((-1 -1, -1 0, 1 0, 1 1, 0 1, 0 -1, -1 -1))',-1));

ST_MakeValidを試してみると

select st_astext(st_makevalid(geom)) from test;
MULTIPOLYGON(((-1 -1,-1 0,0 0,0 -1,-1 -1)),((0 0,0 1,1 1,1 0,0 0)))

のように2つのポリゴンに分けてくれたことを確認できます。

その他の図形

個人的に遭遇するのは、なんでこうなったというようなヒゲなんかが残ってるやつが多いです。

insert into test(geom) 
values(st_polygonfromtext('POLYGON((0 0, 0 1, 1 1, 1 1, 0 1, 0 3, 3 3, 3 0, 0 0))',-1));


ST_MakeValidを試してみると

select st_astext(st_makevalid(geom)) from test;
GEOMETRYCOLLECTION(POLYGON((0 0,0 1,0 3,3 3,3 0,0 0)),LINESTRING(0 1,1 1))

この場合は、ポリゴンとラインに分けてGeometryCollectionにして返してくれます。


後は中抜けポリゴンを作るために一筆書きしちゃったやつ。

insert into test(geom)
values(st_polygonfromtext('POLYGON((0 0, 0 1, 1 1, 2 1, 2 2, 1 2, 1 1, 0 1, 0 3, 3 3, 3 0, 0 0))',-1))


ST_MakeValidを試してみると

select st_astext(st_makevalid(geom)) from test;
GEOMETRYCOLLECTION(POLYGON((0 0,0 1,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1)),LINESTRING(0 1,1 1))

この場合も、ポリゴンとラインに分けてGeometryCollectionにして返してくれます。

ここまでの結論

単純な図形で試した限りではきちんとvalidな図形に分けてくれます。使えそうな感じです。