トップ地図アプリMap > OSMバイナリレコードの管理

OSMバイナリレコードの管理

はじめに

OSMバイナリレコードの管理は地図アプリのパフォーマンスに大きな影響を与える。

低ズームでは、広域な地図データが必要となるため、予め、レコードの絞り込みや簡単化が必要となる。 現在は、低、中、高ズームに分割しているが、可能ならば、低、高ズーム分割としたい。

例えば、zoom 15以上では、zoom 13で分割されたバイナリレコードを使ってタイル画像をレンダリングする。 一つのバイナリレコードファイルには多数のレコードが含まれている。 このため、一つ一つのレコードを独立したオブジェクトとして管理すると、 オブジェクト管理に伴うオーバヘッドが強大となり、メモリ不足に陥る。 このため、ファイルをそのまま byte配列データとしてメモリに読込んでおく。 タイルのレンダリングに使われるレコードはごく一部となる。それらのレコードだけをオブジェクトとして取り出す。

class Block

OSMバイナリレコードは class Block で管理している。メンバーを下に示す。

現在は 40ブロックを配列で管理している。

広範囲な地図を見れば、ブロックの入れ替えが起きるが、日常の散歩などでは、 ブロックの入れ替えはほとんど起きない。一度読み込まれるだけ、入れ替えなしで終わる日が多いであろう。

入れ替えは、LRU方式である。すなわち、もっとも長時間利用されていないブロックが入れ替え候補となる。

レンダリングはマルチスレッドで行われるため、現時点で、何スレッドが利用中かを int ref_count で 管理している。全てのブロックが有効なとき、新しいブロックが要求された場合、 ref_count が 0 で、最終参照時間 time が最も小さい(古い)ものを廃棄して、ここに新ブロックを読み込む。

ファイルパス path は src、range、zoom、x、y から一意的に決まるものであり、必ずしも、 class Block のメンバーとする必要はない。

public class Block {
    static final int MaxBlocks = 40;
    static final Block[] blocks = new Block[MaxBlocks];

    int ix;                 // Block番号
    Tile.Source src;        // japan、kanto
    Tile.Range  range;      // 低、中、高ズーム
    int zoom, x, y;         // ブロック座標

    String path;            // ファイルパス
    int ref_count;          // 参照スレッド数
    long time;              // 最終参照時間
    byte[] vals;            // OSMバイナリレコード(ファイル全体をbyte配列として読込んだもの)
}

全体の動作

Map の onDraw でタイル(zoom, x, y)の要求が起きる。

リファレンス