OSM地図レンダリング用のOSMバイナリレコードファイルは当面 Map4 と同じとする。
OSMにずっと以前に登録された店などは今はない可能性もある。必要に応じて、登録日を表示したい。 また、場合によっては登録者が分かるといい。
現在は、osm_id は特殊なタグ(key,val)として登録できるようにしているが、 使い勝手が良くないこともあり、実際上は osm_id を含めていない。 デバッグのやりやすさを考えれば、bbox の前か後ろに置かれている方がよい。
これらの項目をレコードに含めれば、ファイルサイズは1、2割増えるであろう。 パフォーマンス上は問題ないであろう。例えば、2割増えても、zip圧縮すれば、 ファイルサイズは今よりも小さくなる。しかし、解凍時間が加わるため、 ファイル読み込み時間は短縮されるとは限らない。
まずは Map4 を踏襲して、次のようにしている。
head, {lon,lat}, tags_length, {key,val}* ... point head, bbox, num_nds, {lon,lat}*, tags_length, {key,val}* ... line/polygon head, bbox, num_polys, {num_nds, {lon,lat}*}*, tags_length, {key,val}* ... multipolygon head: 第0,1bit(0x03) 0: point、 1: line、 2: polygon、 3: multipolygon 下位3バイト レコード長(headを含む)
しかし、OSMバイナリレコードファイル形式は Map4の一つ前に戻すことも考えている。マルチポリゴンの場合、 ポリゴン毎のノード数を前に置き、その後に、座標値列データを連続して置く。
この方がプログラムが分かりやすくなる。
現在は osm_id は特殊な (key,val) の一つとしているが、osm_id を独立項目にすることも検討している。 シンプルな建物やマイナーな道路などでは osm_id は省けるようにしたいため、head か bbox の次がよいだろう。
head, {lon,lat}, tags_length, {key,val}* ... point head, bbox, num_nds, {lon,lat}*, tags_length, {key,val}* ... line/polygon head, bbox, num_polys, {num_nds}*, {lon,lat}*, tags_length, {key,val}* ... multipolygon head: 第0,1bit(0x03) 0: point、 1: line、 2: polygon、 3: multipolygon 下位3バイト レコード長(headを含む)
Map4では予めサイズの異なるバッファプールを確保して、最適なサイズを割り当てるようにした。 ガーベージコレクションは減るが、適切なサイズとバッファ数を求めるのが難しい。 常時、使用メモリが大きくなるのも、パフォーマンス上好ましくないと思われる。 よって、以前のように、動的確保、解放方式に戻す。
Map4と同じであり、当面、大きな変更はしない。
統計では uid、(user、) を知りたいことがある。 Android機に読込むファイルには要らないかもしれないが、あってもさほど邪魔にはならない。 osm_id、timestampは含めたい。2038年問題を考えると、timestampは 8バイトが望ましいが、 地図システムでは高精度はいらない。時:分または日付だけでもよい。よって、4バイトで十分である。
osm_id は、node に対しては4バイトでは足りない。way、relationは4バイトでもよいが、 4バイトの節約は大した利益を生まないので、一律8バイトとする方がいいだろう。
uid(4)、timestamp(4)、osm_id(8)を追加すれば、ファイルサイズは 10数%増える。 ファイル読み込み時間自体はその分増えるが、パフォーマンス全体の増え方はそれより小さいであろう。
日本地図のマッパーは変換表を使えば 2 バイトで表せるだろう。 数件のレコードにしか現れない uid は省略してもいい。timestampは日付だけであれば2バイトで表せる。 osm_idも8バイトはpointレコードのみとすれば、レコード当たり8バイト強の増加ですむ。 しかし、約8バイト節約の代償として、プログラムが少し複雑になる。 経験上、プログラムを複雑にするのは得策ではない。素直に16バイト追加した方がよい。
Map4はガーベージコレクションを気にして、複雑にしすぎた。一からプログラムを作り直そう。
Map4では座標値列データエリアを再利用している。これが、少々複雑で、プログラムがパッと見ただけでは分からない。 float[] Renderer#points、int Renderer#ixPoints、int OSM#offPnts などが関連している。 OSMバイナリレコードごとではなく、複数レコードで一本化しているのかも知れない。 効率を考え、空間検索で抽出された全レコード分を points 配列に置いているのであろう。
必要サイズが分からないため、倍々で増やしている。最終的には余分なメモリが確保される無駄がある。 倍々ではなく、例えば、1.5倍とすれば、この無駄は減るが、再割り当て回数が増える。
よって、座標値データエリアは float[] OSM#points に置くことにする。
色々シンプル化しているが、まず、バス路線(細い青線)だけ描画された。 使用メモリは 150~250MB である。
ログディレクトリがなかった場合、生成するようにした。
陸地ポリゴンが正常に描画されることを確認した。 ただし、このまま先に進むのではなく、OSMのデータを見直したい。
OSMの配列メンバーの再利用はやめる。動的に確保して、レンダリングが終わったら解放する。
readAll /storage/36C5-1401/Map5/dat/lands-high6/56/25.dat 1219218