LoginSignup
13
16

More than 5 years have passed since last update.

Shapefile を tippecanoe でベクトルタイル変換して tessera 経由でブラウザ確認するまで

Posted at

STEP 1: Shapefile を GeoJSON ファイルに変換する

GDAL/OGR は手元の OS X では Java6 依存性があるように表示されてしまうので、ここは迷うことなく GeoRuby を使って Ruby で処理する。ストリームを意識しやすいので良い。次の togeojson.rb を使って

$ ruby togeojson.rb | gzip -9 > some.geojson.gz

等とする。tippecanoe はストリームが切れていても終末の処理を適当にしてくれるので、ファイルの完成を待たずに次のステップに進んでも良い。

スクリプトは次のとおり。属性の文字コードを変換すべきかどうかは、Shapefile と GeoRuby の細かな特性に依存すると思うので、手元のデータ・手元の環境に合わせて調整するのがよい。

require 'rubygems'
require 'find'
require 'json'
require 'georuby'
require 'geo_ruby/shp'
#require 'geo_ruby/geojson'

def process(shp_path)
  $stderr.print "processing #{shp_path}.\n"
  geojson_path = shp_path.sub(/shp$/, 'geojson')
  s = []
  GeoRuby::Shp4r::ShpFile.open(shp_path) {|shp|
    shp.each {|r|
      r.data.attributes.each{|k,v|
        if v.class == String
          # 属性の文字コードを Shift_JIS から UTF-8 に変換する
          r.data.attributes[k] = v.encode('UTF-8', 'CP932')
        end
      }
      if $first
        $first = false
      else
        print ",\n"
      end
      r.geometry.with_m = false
      r.geometry.with_z = false
      print JSON.dump({
        "type" => "Feature",
        "geometry" => r.geometry,
        "properties" => r.data.attributes
      })
    }
  }
end

$first = true
print <<-EOS
{"type": "FeatureCollection", "features": [
EOS
count = 0
Find.find('.') {|path|
  next unless /shp$/.match path
  next unless /RdCL/.match path # "RdCL" がファイル名に入っている場合のみ処理
  next if /(NNFPt|NRPt|CSPt|PFPt|DEM)/.match path # 属性・分量の問題で後回し
  count += 1
  process(path)
  #break if count == 100
}
print <<-EOS
]}
EOS

Tippecanoe で GeoJSON をベクトルタイルに変換する

https://github.com/mapbox/tippecanoe
にある tippecanoe をインストールする。

$ brew install tippecanoe

手元にあるのは中縮尺・大縮尺のデータなので、とりあえず閲覧するために z=15〜18 でベクトルタイルを作成したりしている。(これは手元にあるデータによって変わってくる。)

$ gzcat some.geojson.gz | tippecanoe -z 18 -Z 15 -t . some.mbtiles

ここで、 -t . とするのは作業ディレクトリをカレントディレクトリにするため。たいていの Shapefile ベースのデータでは問題なく処理してくれるのが tessera のありがたいところだけれども、処理の特に後段のところで、ややテンポラリを多く使う場合がある。私は残り容量の少ない MacBook Air (11-inch, mid 2011) で処理をしているので、データが置かれているカレントディレクトリ(安い USB HDD)にテンポラリを置くことにしている。それでも、劇的に速度が低下するという感じはない。

tessera でベクトルタイルを閲覧してみる

ここから先は node.js による処理になる。一部、node のバージョンに依存するライブラリもあるので、nodebrew で node / npm を導入したほうが良いかもしれない。

ソフトウェア導入についてこれから説明するが、記憶によるところなので、依存性処理によって不要になるコマンドが入っているかもしれない。それぞれのモジュールについての覚書を兼ねている。

$ npm install mbtiles tilelive tilelive-mapnik

↑このあたりは必要だと思うが、後段の tessera 導入で自動的にインストールされるかもしれない。

$ npm install tessera

サーバとして動いてくれる tessera を導入する。

$ npm install tilelive-vector tilelive-xray

今回、ベクトルタイルのデータを閲覧するので、上記のモジュールが必要になる。特に、tilelive-xray が重要。スタイルをつけていないデータを上手く表示してくれるための機能らしく、tilelive-xray を導入していないと、tessera がエラーメッセージを出して終了してしまう。

また、導入すべき node モジュールが足りないと、tessera でエラーが出る。次のようにしてモジュールを一覧することにより、推理して頂くのがよい。

$ npm find tilelive

実際にサーバを動かすには、次のようにする

$ tessera mbtiles://./some.mbtiles

これで、localhost にサーバが立ち上がるのでブラウザで Leaflet ベースのウェブ地図として最低限閲覧することができる。

ただし、この方法で tessera から送信されるのは、tessera が(たぶんオンデマンドでレンダリングした)PNGタイルである。まさに、Mapbox Studio 的なアプローチで、ぎりぎりサーバサイドレンダリングを実施している。クライアントサイドレンダリングを試してみる方法は、後ほど記載することにしたい。

13
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
16