渓流釣りアプリの開発、今回は大きな転換点でした。アプリの中にドカンと入っていた河川データを外に出して、必要な場所のデータだけをその都度ダウンロードする方式に切り替えました。
117MBの河川データ問題
前回まで、北海道の河川データをまるごとアプリに組み込んでいました。これが約117MB。北海道だけでこのサイズです。
全国47都道府県に対応しようとすると、単純計算で2〜3GB。App Storeのダウンロードサイズ制限をはるかに超えてしまいます。これはまずい。
圧縮すれば多少は小さくなりますが、全国分だと焼け石に水。根本的に考え方を変える必要がありました。
「使った場所だけ取ってくる」方式
そこで発想を転換。アプリには河川データを一切持たせず、ユーザーがアクセスした場所のデータだけをダウンロードしてキャッシュする方式にしました。
イメージとしては地図アプリと同じです。Google マップも世界中の地図データを全部スマホに入れているわけではなく、表示している場所の周辺だけを読み込んでいますよね。それと同じことを河川データでやります。
日本全国を約1km四方のマス目に区切って、それぞれのマスに含まれる河川データをひとつずつファイルにしました。全国で約28万ファイル。1ファイルあたり平均2KBほどなので、検索1回で必要なデータ量はわずか160KB程度です。
湖が川扱いされていた
データを整理していて気づいたのですが、湖沼データがまったく取り込まれていなかったんです。阿寒湖とか洞爺湖とか、湖も含めて全部「河川」として扱っていた状態。
せっかくなので河川データと一緒に湖沼データも統合しました。将来的には地図上に湖の範囲を表示できるようになります。
全国28万タイルのアップロード
北海道で動作確認ができた後、全国分のデータを生成してアップロードしました。
28万ファイルを20並列でアップロードして約90分。途中で9件だけ失敗しましたが、失敗ログからすぐに特定できたのでリトライで全件成功。大量データの処理では失敗した時にどこで失敗したか分かる仕組みを入れておくのが大事ですね。
表示が遅い問題、意外な解決法
データの配信方式を変えたところ、新たな問題が。川の流れを地図上に表示するのに時間がかかるようになってしまいました。
たくさんのデータをダウンロードして、そこから線を組み立てて描画する…という処理が毎回走るので、場合によっては15秒以上かかることも。
ここで発想を転換。線の描画結果を「画像」として保存しておくことにしました。一度だけ画像を作っておけば、見る側は画像1枚を読み込むだけ。36KBの画像をダウンロードするだけなので一瞬です。
メルカトル図法の罠
画像を地図の上に重ねて表示する方式にしたところ、面白い問題が起きました。地図上に描いた円が、縦長の楕円になっている。

原因は地図の「メルカトル図法」。世界地図でグリーンランドが実際よりデカく見えるアレです。緯度によって縮尺が変わるので、単純に座標を変換して円を描くと歪んでしまう。特に北海道のような高緯度だと目立ちます。
解決策は、円だけは画像ではなく地図アプリの機能で直接描画すること。川の線は画像、円と文字は地図機能、という使い分けにしたらキレイに表示されるようになりました。
数字で振り返る
| Before | After | |
|---|---|---|
| アプリ内の河川データ | 117MB | 0MB |
| 対応地域 | 北海道のみ | 全国 |
| 閲覧時のデータ量 | 数百タイル | 画像1枚(36KB) |
アプリのサイズが大幅に軽くなり、しかも全国対応になりました。一石二鳥どころか三鳥くらいの改善です。
次のステップ
湖沼データを地図上に面として表示する機能と、引き続き画面の改善を進めていきます。


コメント