8年ほど前、週1日程度は出かけていたと思うが、概して暇になったので、 神奈川、東京などで散歩や軽いハイキングをすることが多くなった。 方向音痴のため、モバイル地図が欲しくなった。
当時でも通信費はそれほどかからなかったかも知れないが、 たかが地図のために通信費はもったいないという思いから、ネットなしで使える地図を目指した。
スタートから国土地理院地図と OpenStreetMap(OSM)[1] をサポートした。 国土地理院地図はダウンロードしたタイル画像地図を表示するだけなので、簡単である。
一方、OSMはxml形式のデータからタイル地図をレンダリングする必要があるため、桁違いに難しい。
全てフリーソフトで構築する方法が主流であるが[2]、自分の場合、プログラミングが好きなことと、 個人利用で、オフライン利用であるから、サーバーは要らない。
geofabrik[3] からダウンロードした japan-latest.osm.pbf ファイルを osm2pgsql を使って PostgreSQL/PostGISデータベースにインポートする。 レンダリングソフト Mapnik を使って、タイル地図画像ファイルを生成した。
Mapnikを使うに当たっては、自分にとっては初めての python の知識も必要であり、 Mapnik独自のレンダリング用のスクリプトの理解も必要であった。
また、当然、GPSデータの入力も必要であり、 そんなこんなで、最初のシステム開発には2,3か月を要したと思う。
最初の1年は10インチの Windowsタブレットを持ち歩いた。 しかし、これでは持ち運びが大変であり、1年で6インチタブレットに変更した。
今はまた osm2pgsql の Windows版があるが、数年、使えない時期があった。 そのうち Mapnik も Windows 版がサポートされなくなった。
Oracle VM VirtualBoxを導入して Ubuntu で Mapnik を使うことにした。 このとき、python を使うことをやめ C++ で Mapnik を動かすようにした。
OSM は発展を遂げており、関連フリーソフトもこれに同期して、高度化し、パフォーマンスも 向上している。
Mapnik(osm2pgsql)によるレンダリングのカスタマイズには Lua言語が使われるようになり、 しばらくの間この言語も使った。
PostgreSQL関連でもPL/pgSQLを使ったことがある。
プログラミングが大好き人間でも、これだけ振り回されるといい加減うんざりしてくる。
フリーソフトから徐々に離れて、極力、自前プログラムに移行した。
7年目にタブレットからスマホに移行して、ますます、その傾向を強くした。 スリムで分かりやすくハイパフォーマンスな地図アプリに向かって進んでいる。
最初のスマホ用地図アプリでは、陸地ポリゴンを描画するだけのために、 PostgreSQL/PostGIS を使っているが、新地図アプリでは、これもやめて、 Overpass APIで海岸線データを取得して、陸地ポリゴンを描画する予定である。
Overpass APIは OSM の最初の API よりも桁違いに強力である。
1年前後かけてOSMバイナリレコード作成を全面的に見直した。 パフォーマンス向上もさることながら、プログラムの分かりやすさを追求する。
しばらくして、独自方式をやめた。シェイプファイルを PostgreSQL/PostGIS にインポートして、 分割ファイルと低ズーム用ファイルをそのまま使う方式に戻した。 パフォーマンスは独自方式よりやや劣るが、レンダリングした結果を再利用する方式に変えたので、 問題はない。
検索は二分探索(binary search)とした。近傍の値の検索が続くときは順次検索(sequential search) でよいため、パフォーマンス上は全く問題がないことが分かった。
概ね完了し、現在使用中の地図アプリより進歩した面はあるが、複雑化した面もあり、若干の不安もある。 やはり、もっとシンプルにしたいという思いがある。
パフォーマンスに拘り、複雑化したことを否定できない。 どこかでチョンボして、パフォーマンスロスが潜在している懸念もある。
地図アプリをパソコンからスマホに移植した時、一時的に3つのアプリに分割していた。 このときは、HTTP通信を使っていた。 ほどなくして、一つのアプリに統合した。
今度は地図表示アプリと地図サーバーアプリに二分してみる。タイル画像ファイルの作成はサーバー、 読み込みは地図表示アプリとなるが、リクエストとレスポンス(タイル画像作成完了通知)は broadcast を使う。
国土地理院地図のタイル画像のダウンロードは取りあえず、地図表示アプリで行う。 補助的使用のため、当面、先行ダウンロードは行わない。先行ダウンロードも行う場合には、 ダウンロードを地図サーバーに移す方がよいと思われる。
可変長バイトコードは有効かどうか再考したい。3.3GBから2.6GBへ2割以上縮小しているが、 プログラムは複雑化している。
可変長バイトコード自体では3、4割の圧縮効果があるが、空間検索高速化のために、 管理データが必要となった。以前の差分コードでも2割前後の圧縮効果はある。
OSMバイナリレコード形式も課題となる。タグの追加で enum を変更すると、 一からデータの作り直しになるのもできれば避けたい。
現在の OSMのタグ仕様を全面的にチェックして、全タグを盛り込むのも楽ではない。 最初のフェーズ Encoder では、enum によるコード化は行わない案もある。 タグ部のサイズは数倍の大きさになるとしても、全体の大きさは2倍にはならないだろう。
way_area や中心座標をレコード形式の表に出すか、tag部に含めるかも悩ましい。 tag部に含めた方が見かけはシンプルで、tag部のどこにあってもよい。 表にだすと、有無を表すフラグがいる。
可変長バイトコードはやめる。name:en、name:ja もやめ、文字列コードは utf-16 に戻して、 バイナリレコードは short配列に戻した方がよいだろう。あるいは、タグ部を4バイトの倍数に調整して、 レコードをメモリ上はint配列とした方がいいだろう。
元々、簡単化を目指したが、そうはなっていないので、再度、仕切り直しである。