sos の 作業メモ

プログラミングや英会話学習、マイルや旅行、日常生活など。最近はWebFormなASP.NETのお守りがお仕事です。

日々の生活にhappyをプラスする|ハピタス Gポイント

Google Maps Android API v2で軌跡描画

どれくらいの数のPolylineが描画できるのか の記事でも書きましたが、やっとこさ軌跡を地図上にプロットできるようになりました。

せっかくなので、処理の概要メモっときます。

刻々と追加される座標を描画

プロットするべき座標値は、Serviceを使ってSQLiteなDBに刻々と追加していきますので、 マップ側も追随して描画していく必要があります。

通知 vs 問い合わせ

マップ側で新しい値を取得する方法ですが、通知と問い合わせのどちらかというより、組み合わせたものにします。

サービス側からマップ側へは座標が更新されたことだけを通知し、マップ側は一旦キューに積むかフラグを立てておいて、追加処理が可能になった時にサービスに対して新しい座標値群を問い合わせる形です。

Polylineの節点群ってimmutableなんですよ

マップに追加したPolylineオブジェクトの節点は、座標を変えることも数を増減することもできません。
厳密には、オブジェクトから節点リストのコピーを取得し、それに手を加え、オブジェクトに節点リストを再設定するという道は残されていますが、なんとも二度手間。

新しい座標値がやってくる度にpolylineの節点も増やさないといけないので、過去からの全ての節点をひとつのインスタンスにいれるのも駄目。 とりあえず、一つのPolylineオブジェクト対して500節点、そしてマップに追加するPolylineオブジェクトは最大60個と制限して、一番後ろのPolylineオブジェクトを毎回生成し直すことにしました。

Polylineを生成するためには、PolylineOptionsのインスタンスが必要ですが、このオブジェクトは節点の追加と削除が可能なので、最後のPolylineオブジェクトを生成するときに使ったPolylineOptionsのインスタンスを保持したままにしておいて座標が追加される度にこれを更新し、マップに登録した最後のPolylineのインスタンスを削除して、更新されたPolylineOptionsでマップに新規のPolylineを追加していく流れとなります。

オブジェクトの更新も最低限に抑えられるし、まぁなんとかいけるんじゃないかと。

マップ側の処理を整理

  1. PolylineOptions格納用のリスト(optsList)を作成
  2. マップに登録されているPolyline格納用のリスト(polylineList)を作成
  3. キュー/フラグをみてサービスから新しい座標値群を取得
  4. optsListからPolylineOptionsを取り出し(なければ新規作成)、座標値群を追加。 節点数が上限に達した場合は、新しいPolylineOptionsを生成して最後の座標をコピーしoptsListに追加
  5. optsListに追加されたオブジェクト数がPolylineの上限数以下になるまで先頭から削除
  6. ここからはUIスレッドでの操作
  7. polylineListが空でなければ最後のPolylineを取り出し、GoogleMapオブジェクトから削除
  8. polylineListとoptsListのオブジェクト数がPolylineの上限数以下になるまでpolylineListの先頭からPolylineを取り除き、GoogleMapオブジェクトからも削除
  9. optsListの先頭からGoogleMapオブジェクトにPolylineを追加。最後のPolylineOptionsだけを残してあとはoptsListから取り除く

3〜6を繰り返す

これで逐次追加系のPolyline表示が完成しました。万歳! 他にやりようはあるんでしょうけど、とりあえずこれで上限までテストしてみます。

2013/09/02追記

Google Maps SDK for iOS で 軌跡描画 - sos の 作業メモ

iOS版だとどんな実装になるか書いてみました。