トップ地図アプリMap3 > 地図にその日のGPS軌跡を表示する

地図にその日のGPS軌跡を表示する

はじめに

現在は、タイル画像を画面キャンバスに描画した後、画面キャンバスにその日のGPS軌跡を上書きしている。 簡単であるが、スクロールするごとに上書きを行うため、処理時間がかかる。

タイル自体にGPS軌跡を上書きしてそれをタイルキャッシュにしまっておけば、スクロール時の上書きは要らないため、 レスポンス上は有利である。GPS軌跡の上書きをやめたり、再開するときは、一旦、全キャッシュをクリアすることになるため、 その時は時間がかかる。必ずしも、全タイルキャッシュをクリアする必要はなく、GPS軌跡の上書きが起きたタイルだけでよいが、 それなりのプログラム追加が必要となる。

ここでは、まず、これまで通りの方法をとり、パフォーマンス向上については後の課題とする。

まず、MapXで取得済みのGPSログデータは正常に描画できた。新たなログ追加で表示誤りがあり、アプリがエラーストップした。 急がずに、じっくり取り組もう。

その日のGPS軌跡をメモリに保持する

とりあえずは、緯度、経度、高度のみを保持する。 OSMレンダリングでは緯度、経度は整数化しているため、それに合わせる。

class GPSLog {
    final static int E7 = 10000000;
    static List listLogs;    // 今日のGPSログ

    int ilon, ilat, ialt;

    public GPSLog(String loc) {
        String[] v = loc.split(",");
        ilon = (int) Math.round(Double.parseDouble(v[1]) * E7);
        ilat = (int) Math.round(Double.parseDouble(v[2]) * E7);
        ialt = (int) Math.round(Double.parseDouble(v[3]));
    }
}

その日のGPS軌跡を描画する

    void drawToday(Canvas canvas) {
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(1.5f*Map.Scale);
        List<GPSLog> logs = GPSLog.listLogs;
        if (logs == null || logs.size() == 0) return;
        float xB = getX(logs.get(0).ilon);
        float yB = getY(logs.get(0).ilat);
        LocalDateTime tB = logs.get(0).ldt;
        for (int n = 1; n < logs.size(); n++) {
            GPSLog log = logs.get(n);
            float xE = getX(log.ilon);
            float yE = getY(log.ilat);
            LocalDateTime tE = log.ldt;
            if (ChronoUnit.MINUTES.between(tB,tE) < 1) {
                paint.setColor(log.speed < 3 ? Color.BLUE : Color.BLACK);
                canvas.drawLine(xB, yB, xE, yE, paint);
            }
            xB = xE;
            yB = yE;
            tB = tE;
        }
    }

履歴およびメモ

2023.11.28 アプリのアイコンを 地図アイコン に変えた

デフォルトでは Manifest の application は次の通りである。

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Map3"
        tools:targetApi="31">

次のように変更してアイコンを地図アイコンに変えた。

        android:icon="@drawable/ic_map_blue24"
        android:roundIcon="@drawable/ic_map_blue24"

MapXはアプリ画面でタイトル Map の左にこの地図アイコンを表示しているが、その方法が分からないので、 当面、このアイコンは表示しない。ネット検索でコードによる方法は見つかったが、もっと簡単な方法があるだろう。

2023.11.28 アプリのラベルを Map に変えた

デフォルトでは プロジェクト名 map3 である。res/values/strings.xml の app_name を map3 から Map に変えた。 これでアプリ名が map3 から Map に変わった。

2023.11.27 地図上に移動ルート(GPS軌跡)が表示されることを確認した

多少の問題点が残っている可能性もあるので、慎重に、前進したい。

2023.11.27 起動時に地図が表示されない

画面に触れると、わずかなスクロールが起き、地図が表示される。MapXなどでも似た経験がある。

起動後最初の onDraw では、キャッシュが空のため、リクエストだけが生まれる。 RenderThreadがこのリクエストを受けて、順次、タイル画像を準備して、invalidate() を実行する。 これにより、onDraw が起こり、タイルの描画が起きるはずだが。

最初の onDraw は実行されている。その後、最初の alloc がうまく行っていないようだ。 そもそも、最初の onDraw でリクエストが生まれていない。

この段階では W, H が未設定であることがわかった。この場合、onDrawで設定することにより解決した。

2023.11.27 GPSLogの座標について

現在は極座標を整数化したものとしている。OSMレンダリングでは極座標ではなく、XY平面座標としている。 このように変更した方が描画時の座標変換処理が楽になる。 描画時間短縮は2、3割程度かもしれないが、XY平面座標の方がレンダリングと同じになるので、いずれ、変更したい。

2023.11.26 メニューを用意した

すぐには要らないが、いずれ必要になるので、メニューを実装した。

リファレンス

[1] iOS向けウォーキングアプリ『ALKOO(あるこう)』提供開始
[2] トラックログの標高値を書き換える:スーパー地形アプリ
[3] 『ブラタモリ』ファン必携、高低差好きにおすすめの3D地図アプリ「スーパー地形」