GeometryCollection から点と線を削除して MultiPolygon にする方法
標記のこと、buffer(0) でできることを確認しました。
d:id:hfu:20071220 で課題としていた、
Geometry の set-theoretic methods をうまく使って LineString と Point だけをエレガントに消せるかもしれません。
http://d.hatena.ne.jp/hfu/20071220/1198130913
について、buffer(0) で消せることが分かったので、実証してエントリします。
geotools.rb にメソッドを追加
検証作業を簡単にするために、geotools.rb に Geo::create_geometry_collection を加えました。引数に Geometry の配列を与えると、それらの GeometryCollection を返します*1。
geotools.rb には、以下の関数が追加されています。
- Geo::create_geometry_collection([geom1, geom2, ...])
- Geo::create_multi_point([point1, point2, ...])
- Geo::create_multi_line_string([line_string1, line_string2, ...])
- Geo::create_multi_polygon([polygon1, polygon2, ...])
buffer(0) で GeometryCollection から Point と LineString が消せることの実証
buffer(0) で GeometryCollection から Point と LineString が消せることの実証スクリプトは、以下のようになりました:
# test_gc_to_mp.rb require 'geotools' # 模擬データを作る pt0 = Geo::import_wkt_geometry('POINT (0 0)') ls0 = Geo::import_wkt_geometry('LINESTRING (0 0, 1 1)') pg0 = Geo::import_wkt_geometry('POLYGON ((0 0, 1 1, 1 0, 0 0))') pg1 = Geo::import_wkt_geometry('POLYGON ((1 0, 2 1, 2 0, 1 0))') gc = Geo::create_geometry_collection([pt0, ls0, pg0, pg1]) # GeometryCollection から Point と LineString を排除して MultiPolygon にする gc = gc.buffer(0) gc = Geo::create_multi_polygon([gc]) if gc.getNumGeometries == 1 # 表示 p gc.toString
$ ruby test_gc_to_mp.rb
DEBUG: rjb primitive_conversion mode
"MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)), ((1 0, 2 1, 2 0, 1 0)))"
まとめ
GeometryCollection#buffer(0) により、GeometryCollection に含まれる LineString や Point を消去することができます。
*1:それほど大げさな処理ではないのですが、Rjb と JRuby の間で微妙に異なってくる処理を吸収するために、処理を geotools.rb の中に入れておきました。