GeoTools で地球地図起源の海岸線データを単純化する その3
d:id:hfu:20071211, d:id:hfu:20071212 の続きとして、ポリゴンの単純化を実際にやってみました。
geotools.rb の改変
geotools.rb を改変し、ポリゴンの単純化に必要なクラスを取り込むようにしました。このエントリのスクリプトを実行するには、http://svgmapdata.sakura.ne.jp/geotools/ にある geotools.rb (Time-stamp: <2007-12-13 05 : 47 : 35 hfu> 以降)を使ってください。
ポリゴンの単純化に必要なクラスとは
ポリゴンの単純化をしてくれるクラスには以下の2つがあります:
- com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier
- 地図学的なベクトルデータの単純化アルゴリズムとしては古典的であるらしい、Douglas-Peucker アルゴリズムを使って幾何を単純化するクラスです。ポリゴンを単純化する場合、単純化後のポリゴンも valid であることは保証されるそうです。ただし、単純化の結果、ポリゴンが分割されたり線分になったり、穴ができたり消えたりすることがあり、それがいやなら後者の TopologyPreservingSimplifier を使う必要があるとのことです。また、後者の TopologyPreservingSimplifier よりも処理が高速であるそうです。
- com.vividsolutions.jts.simplify.TopologyPreservingSimplifier
- 入力幾何と同じ次元と、入力幾何と同じ構成要素数を確保しつつ単純化をしてくれるクラスです。
上記のクラスのいずれも、
static Geometry simplify(Geometry geom, double distanceTolerance)
なるメソッドを持っており*1、これを使うことができます。第二引数の distanceTolerance で、単純化の強さを指定することができます。
単純化実験スクリプト
いくつかの distanceTolerance でこれらの Simplifier を試し、その結果を Shapefile に格納するプログラムは、以下のようになります。
require 'geotools' simplifiers = %w{TopologyPreservingSimplifier DouglasPeuckerSimplifier} 5.times do |i| simplifiers.each do |simplifier| tolerance = 0.1 ** i fn = "#{simplifier}_#{sprintf('%.4f', tolerance)}" Geo::FeatureList.open("#{fn}.shp") do |w| Geo::FeatureList.foreach('odai.shp') do |f| g = f[:the_geom] eval "g = Geo::Tools::#{simplifier}.simplify(g, #{tolerance})" print "#{fn} has #{g.getNumPoints} points.\n" w.write({:the_geom => g}) end end end end
十進経緯度のまま単純化をしているので、地上の長さの尺度で考えると、単純化の強さが南北方向と東西方向で異なり、また南方地域と北方地域で異なることになります。より性質の良い単純化が必要な場合には、表示用の座標系に投影してから単純化する必要があるかもしれません。
単純化実験の結果
Douglas-Peucker, toleranceDistance 0.0001 度
構成点の数は全国分で 51840 点となっています。オリジナルのデータからそれほど構成点数が変わっていませんので、この単純化設定には、それほど価値はないかもしれません。
Douglas-Peucker, toleranceDistance 0.001 度
構成点の数は全国分で 36309 点となっています。構成点数は半分程度で、見た目はあまり変わらないという点で、使える設定かもしれません。
Douglas-Peucker, toleranceDistance 0.01 度
構成点の数は全国分で 5166 点となっています。構成点の数が 1/10 程度で概略が分かるという点で、なかなか良い単純化になっています。
Douglas-Peucker, toleranceDistance 1 度
構成点の数は全国分で 19 点となっています。思い切った単純化になっています。
Topology preserving, toleranceDistance 0.0001 度
構成点の数は全国分で 51846 点となっています。オリジナルのデータからそれほど構成点数が変わっていませんので、この単純化設定には、それほど価値はないかもしれません。
Topology preserving, toleranceDistance 0.001 度
構成点の数は全国分で 36755 点となっています。見た目遜色なく、島の数え落としもなく、データ量が半分程度ということで、この単純化設定も使いでがあるでしょう。
Topology preserving, toleranceDistance 0.01 度
構成点の数は全国分で 9153 点となっています。島を数え落とさずにデータ量を 1/5 にして、このくらいの綺麗さなので、この単純化設定もなかなか良いかもしれません。
Topology preserving, toleranceDistance 0.1 度
構成点の数は全国分で 5513 点となっています。ちょっと気持ち悪い単純化になってしまいました。Topology preserving といっても、マルチポリゴンの構成ポリゴンの間での重なりを回避してくれるわけではないようです。