国土数値情報(避難施設データ)のベクトルタイル変換
国土数値情報(避難施設データ)のベクトルタイル変換を行ってみた。国土数値情報(地価公示)データの変換と同じだが、47都道府県分一つ一つクリックする必要はある。OS Xの場合、~/Downloads フォルダに展開されるので、そこをスタートラインにして、次のスクリプトを実行した。
map.rb
require 'find' require 'json' require 'rubygems' require 'geo_ruby' require 'geo_ruby/shp' include GeoRuby::Shp4r module Math def self.sec(x) 1.0 / cos(x) end end def process(r, z) n = 2 ** z lon_deg = r.geometry.x lat_rad = r.geometry.y * 2 * Math::PI / 360 x = n * ((lon_deg + 180) / 360) y = n * (1 - (Math::log(Math::tan(lat_rad) + Math::sec(lat_rad)) / Math::PI)) / 2 prop = {} r.data.attributes.each {|k, v| prop[k] = case v when 'true' true when 'false' false else s = v.to_s /^\d*$/.match(s) ? s.to_i : s end } f = {:type => 'Feature', :geometry => {:type => 'Point', :coordinates => [r.geometry.x, r.geometry.y]}, :properties => prop} print [z, x.to_i, y.to_i, JSON.dump(f)].join("\t"), "\n" end Dir.glob('/Users/hfu/Downloads/P20-*') {|dir| Dir.glob("#{dir}/*.shp") {|path| ShpFile.open(path) {|shp| shp.each {|r| ARGV.each {|z| process(r, z.to_i)} } } } }
reduce.rb
require 'fileutils' require 'json' last = nil geojson = nil $n_tiles = 0 def write(geojson, zxy) path = zxy.join('/') + '.geojson' print "writing #{geojson[:features].size} features to #{path}\n" [File.dirname(path)].each {|d| FileUtils.mkdir_p(d) unless File.exist?(d)} File.open(path, 'w') {|w| w.print(JSON.dump(geojson))} $n_tiles += 1 end while gets r = $_.strip.split("\t") current = r[0..2].map{|v| v.to_i} if current != last write(geojson, last) unless last.nil? geojson = {:type => 'FeatureCollection', :features => []} end geojson[:features] << JSON.parse(r[3]) last = current end write(geojson, last) print "finished. #{$n_tiles} tiles written.\n"
実行
$ ruby map.rb 14 | sort | ruby reduce.rb
これでズームレベル14のベクトルタイルが作成される。34684タイル。