ハンズオン準備のその2です。ハンズオン準備記事の趣旨についてはその1をご覧ください。
#大きな問題は分割する。地理空間情報なら空間的に
https://planet.osm.org/ に示されているとおり、最近の planet.osm.pbf は 42GB ほどあります。このくらい大きなデータをワンパスで通そうとするのは危険です。メモリあふれのような資源問題で失敗する確率が上がりますし、失敗した時の手戻りが大きくなりすぎたりするからですね。
情報工学の世界では、大きな問題は分割するのが定石です。地理空間情報は地理空間的に局所性があります。この局所性を生かして、データを空間的に分割しましょう。
とりわけ今回のハンズオンでは、$200 PC でもベクトルタイルの生産と消費ができることを実証したいわけですから、問題を適切に分割することは、非常に重要なことです。
今回のシナリオでは、いずれデータはベクトルタイルに分割します。であれば、ベクトルタイルと相性の良い分割の仕方をするのが良いです。つまり、ベクトルタイルの切り方と同じ流儀で切って分割しましょう。
#1024でも16384でもなく、4096に分割する。
全世界を、タイルの切り方と同じように分割することを考えます。つまり、z=0なら0分割、z=1なら4分割、z=2なら16分割です。一般には、4 ** z 分割することになります。
ここで、この指数関数の底が4なのが曲者です。地球全体を相手にする場合、現実的に選べるzは、具体的なユーザーストーリーにもよりますが、多くはありません。
ここでは、次のように単純に考えます。
いま、planet.osm.pbf は 42GB あります。z=5 を選んで1024分割すると、ざっくりと平均42MBくらいになりますね。osm.pbf 形式で42GBというと、ちょっと大きすぎるかもしれません。
z=6 を選んで4096分割すると、ざっくりと平均10MBくらいになります。このあたりがちょうど手頃かなと考えました。
z=7 を選んでしまうと16384分割することになります。ここまでたくさんに分けてしまうと、今度はファイルシステム上の取り回しだとか、進捗管理とかが難しくなりそうです。
というわけで、4096分割することにしました。
実装: osmium extract を呼び出すコード
実装ですが、ここは osmium extract を使うことにします。
世界全体を順番に z=6 のモジュールに分割するためのコードを、GitHub に置いています。
運用: 実際に使うモジュールだけしか切り出さない
実際には、上記 index.js の実行には、非常に長い時間がかかります。一つのモジュールを切り出すのに、数時間程度かかるからです。
なお、config.json を工夫して、一回の実行で複数のモジュールを切り出すことを試みることができますが、私の環境では、一回の実行で切り出すモジュールの数を3以上にすると、メモリ不足で実行に失敗することがあります。このため、一回の実行でひとつのモジュールを切り出すようなコードにしています。
手元では、世界を覆う全数のモジュールを切り出そうとすることはせず、必要な少数のモジュールを切り出す作業をするようにしています。
ハンズオンはスリランカで行います。スリランカを含む z=6 タイルは、{z}-{x}-{y} という記法(*)で表現すると、6-46-30 です。リンク先を辿っていただくと見えるように、ちょうどよく枠がはまっていますね。この先、6-46-30.osm.pbf を相手にしていきます。
(*) なお、この記法を what3numbers 記法と呼んでいます。
次回
次回は、6-46-30.osm.pbf を GeoJSON Text Sequence 形式に変換します。ハンズオン内部環境でどのように共有するかについても考えましょう。