トップ地図アプリMap > OSMバイナリレコードファイルの分割

OSMバイナリレコードファイルの分割

はじめに

OSMバイナリレコードファイルはメッシュ(ブロック)分割しておく。 境界ボックスが複数のブロックにまたがる場合、同じレコードを複数のブロックに含める。

非常に多くのファイルに分割されるため、全てのファイルをオープン状態にして、 レコードを追加登録することができない。

メモリ上のバッファに蓄えていき、新たなレコードがバッファに入りきれないときは ファイルに追加書き込みを行い、バッファを空にする。その後、新たなレコードを 追加書き込みする。

バッファのサイズは最大レコード長より小さくても問題はない。

最後に、バッファに残ったレコードをそれぞれのファイルに追加登録する。

バッファはファイル名をキーとした HashMap で管理する。

高ズームでは、全てのレコードをレンダリングに使用する。

中・低ズームではレンダリングに使用するレコードを絞り込む。 また、ノードを間引いて、レコードサイズを小さくする。 このレコードの絞り込みとノードの間引きは、ここで行わず、一つ前の処理で行う方がよいであろう。

分割結果は japan_norm13、japan_norm7、japan_mid7、japan_low3 といったディレクトリ下に置く。 norm13、norm7 はレコードの絞り込みやノードの間引きがない高ズーム用のバイナリレコードであるが、 全てを zoom 13メッシュに置こうとすると、巨大なポリゴンレコードの場合、 極めて多数のブロックに重複しておくことになるため、巨大なレコードは zoom 7 で分割する。

中・低ズームではその配慮をしなくても、それほど重複は起きない。

境界ボックスが巨大となるレコードは改めて削減の努力をする。できれば、高ズーム用も一本化したい。

OSMバイナリファイル形式

この段階での出力ファイルの形式は極めて重要である。現行形式は分かりにくいため、シンプルにしたい。 しかし、シンプルすぎても、地図アプリでの読み込みに苦労する。 試行錯誤の上、現行よりはシンプルでハイパフォーマンスな形式を探りたい。

大半のレコードは座標データは差分により、2バイトx2 で表現できる。 差分コードか否かを特殊タグとして表現すれば、ファイル形式はスマートであるが、 地図アプリでこれを取り出すのに苦労する。やはり、レコードの先頭に管理データがある方がはるかにやりやすい。

最大レコード長はまだ不明であるが、おそらく、3バイト以下ですむであろう。 レコード先頭の4バイトを管理ビット+レコード長とするのが、シンプルであろう。

境界ボックスをバイナリレコードに置くかどうかが課題である。 メモリ上では、パフォーマンス上必須となるであろう。レコードになければ、ファイル読み込み時間は短くなるが、 算出時間がかかる。

head(4),  num_nds(0/2/4), {lon,lat}*, {key,val}*  ... point/line/polygon 
head(4), {num_nds(2/4)}*, {lon,lat}*, {key,val}*  ... multipolygon
head:
  第0,1bit(0x03) 0: point、   1: line、    2: polygon、 3: multipolygon
  第2bit(0x04)   0: 差分座標、1: 絶対座標
  第3bit(0x08)   0: num_nds2バイト、 1: num_nodes4バイト
  下位3バイト   レコード長

来歴

リファレンス