GeoTools で地球地図起源の海岸線データを単純化する
id:yellow_73 さんのエントリから、ポリゴンを単純化する、というお題に需要があると読み取ることができましたので、GeoTools を使ってポリゴンの単純化を実際にやってみました。
美しくて使いにくいデータを、使えるように楽にハンドルできるようにしたい
id:yellow_73 さんのエントリより:
ライトユーザから見たら現実的な応答時間で返せない限りは、「美しさ」がいくらあろうとも意味がないです。
2007-12-10
でも、「美しさ」が感じられないものは、少しでも違う目的で使おうとすると途端に破綻するような、あぶなっかしいものでもあるでしょう。
突き進む人と洗練させる人がいて、お互いに影響しあって少しずつ進んでいくしかないのでしょう。
まさにおっしゃるとおりだと思います。「お互いに影響しあって少しずつ進んでいく」ことは、「そうしたらいいね」というものではなくて、「しかない」とおっしゃるとおり、「そうしないと進めないよね」というものであると思います。その点に関して、
ただ、私は媒介できる人がいるといいなと思うんです。
2007-12-10
という部分、私もとても強くそう思います。ただ、実際には日本の業界の風土で「媒介できる人」が単体で職業として成立することは難しいかもしれないとも思います*1。実際には、いろいろな業態の法人のなかで、比較的小さなチームあるいは個人として、「地理データをハンドルする人」がいる場合が多いと思います。所属する法人たちは、競合さんであったり、発注受注関係であったりもすることもあると思いますので、直接媒介されることが難しい場合もあります。
しかし、ブログを使えば、個人対個人の範囲で、技術の媒介ができます。Web 技術の業界では、それが普通に行われているようですから、地理データのハンドルの分野でも、ブログを媒体にして、これからよりいっそう技術の媒介が行われると良いなと思います。
その意味で、id:yellow_73 が「個人メモを書き散ら」すというのは、技術の媒介にとても寄与していると思います。「書き散らされた」情報は、 その情報を必要としている人に Google が引き合わせてくれます。
ところで、geotools.rb は、地理データのハンドリングを、なるべくストレスなく行えるようにすることを目的にしています。地図屋さんと「ライトユーザ」さんとの間で、何らかの寄与ができたらなと思います。
それ、geotools.rb でできるよ
海岸線データの例でいくと、総描ツールなんかをリリースしてくれる人とか。
http://d.hatena.ne.jp/yellow_73/20071210/p2
とのことなので、「それ、geotools.rb でできるよ」と言うべく、実際に総描(単純化)してみました。以下のような手順になります:
お題の海岸線データを模擬するデータの作成
お題となっている海岸線データを模擬するデータを、みんなの地球地図プロジェクト の地球地図日本バージョン1.1「行政域」データから作ります。
市区町村ポリゴンをマージして、お題のデータの模擬データを作成します。
ポリゴンのマージについては、Dr. JTS こと Martin Davis さんが詳しいのです。彼のブログで勧められている、
Buffer Union: Collect the polygons into a GeometryCollection and run buffer(0) on the collection
http://lin-ear-th-inking.blogspot.com/2007/11/fast-polygon-merging-in-jts-using.html
という方法でマージします。
「お題の海岸線データを模擬するデータ」odai.shp を作成する geotools.rb コードは、以下のようになりました:
# this code works only with JRuby, not CRuby + Rjb. require 'geotools' gf = Geo::Tools::GeometryFactory.new Geo::FeatureList.open('odai.shp') do |w| a = [] Geo::FeatureList.foreach('/Users/hfu/src/bnda_1_1/bnda_1_1.shp', {:whitelist => []}) do |f| a << f[:the_geom] end a_java = com.vividsolutions.jts.geom.Geometry[a.size].new a.each_index do |i| a_java[i] = a[i] end geom = gf.createGeometryCollection(a_java).buffer(0) w.write({:the_geom => geom}) end