世界の測量

Sibling of "Relevant, Timely, and Accurate, " but much lighter and shorter ※自らの所属する組織の見解を示すものでない

GeoJSON Tilesはどの程度使えるのか、試すためのheroku app(1)

いったいどの程度の規模のGeoJSON Tilesがまともに使えるのか、試すためのheroku app作成の第1回。とりあえず、タイルの中にランダムな点を30個置くことを意図したもの。

狙い

ベクトルタイルを扱う既存のオープンソース実装が、どれほどメモリを大切に使っているか検証しなければならないが、検証するには実際に動かしてみるのが一番であるため、実際に動かしてみることを狙う。

やりかた

サーバサイドでダミーデータを作る必要があるので、久々にherokuを使う。
herokuでRubySinatra)のアプリを作るなら、今なら Getting Started with Ruby on Heroku | Heroku Dev Center を参考にすることになる。

ソースコード

いつもながら、改善の余地はある。上記の heroku 標準工程でいうweb.rbの内容は次の通り。

require 'sinatra'

$id = 0
def xz2lng(x, z)
  360.0 * x / (2 ** z) - 180.0 
end

def yz2lat(y, z)
  Math::atan(Math::sinh(Math::PI * (1 - 2.0 * y / (2 ** z)))) * 
    360.0 / (2 * Math::PI)
end

get '/*/*/*.*.geojson' do |z, x, y, n|
  z = z.to_i
  x = x.to_i
  y = y.to_i
  n = n.to_i
  content_type 'text/javascript'
  ret = 
  <<-EOS
{ "type": "FeatureCollection",
  "features": [
  EOS
  n.times {|i|
    dlng = xz2lng(x + 1, z) - xz2lng(x, z)
    lng = xz2lng(x, z) + rand * dlng
    dlat = yz2lat(y, z) - yz2lat(y + 1, z)
    lat = yz2lat(y + 1, z) + rand * dlat
    ret +=
    <<-EOS
    { "type": "Feature",
      "id": "#{$id += 1}",
      "geometry": {"type": "Point", "coordinates": [#{lng}, #{lat}]},
      "properties": {"prop0": "value0"}
    },
    EOS
  }
  ret.chop!.chop!
  ret +=
  <<-EOS

  ]
}
  EOS
  ret
end

get '/' do
  content_type 'text/html'
  <<-EOS
<!doctype html>
<html>
<head>
  <link rel='stylesheet' href='//leafletjs.com/dist/leaflet.css'/>
  <script src='//leafletjs.com/dist/leaflet.js'></script>
  <script src='//raw.github.com/glenrobertson/leaflet-tilelayer-geojson/master/TileLayer.GeoJSON.js'></script>
  <style>
  html, body, #map {
    margin: 0; padding: 0; width: 100%; height: 100%;
  }
  </style>
</head>
<body>
  <div id='map'/>
  <script>
map = new L.Map('map');
map.setView(new L.LatLng(35, 135), 6);
map.addLayer(new L.TileLayer(
  'http://cyberjapandata.gsi.go.jp/xyz/std2012/{z}/{x}/{y}.png',
  {attribution: '地理院タイル'}));
map.addLayer(new L.TileLayer.GeoJSON(
  '/{z}/{x}/{y}.30.geojson'));
  </script>
</body>
</html> 
  EOS
end

結果

http://fakeplasticgeojsontiles.herokuapp.com
2013-11-29現在、タイルあたり30個のポイントデータをダミー供給するようにしてあるつもり。ミスもあるかもしれない。また、今後同一のappで内容を変更していくつもり。

Advent Calendar のネタを自ら消尽している気もするが、タイムリーにやる必要があるので随時リリースしていく。