トップ地図アプリMap4 > 地図アプリ Map4 の第一歩
前ページ

地図アプリ Map4 の第一歩

AndroidManifest.xml

Map3 のものをそのままコピーした[2024.1.25]。

android:theme="@style/Theme.Map3" を android:theme="@style/Theme.Map4" に変更した。

@drawable/ic_map_blue24は Map3 のものを Map4 にコピーした。

位置情報取得サービスは後ほど実装するので、ひとまずは、コメントアウトした。

        <!--service
            android:name=".LocationUpdatesService"
            android:enabled="true"
            android:exported="false"/-->

以上でエラーは取れた。

activity_main.xml

Map3 のものをそのままコピーした[2024.1.25]。

class Map extends View はまだ実装していないので、ひとまず、コメントアウトした。

        <!--com.example.map4.Map
            android:id="@+id/map_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" /-->

ここで、タブレットに繋いで、USBデバッグを開始した。

多くのエラー(15)が出るが、まずは最初のエラーに対応する。 Map3 と同様に、compileSdk、targetSdk を 32 から 34 に変更した。

これで最初の画面は表示された。

  1.  Dependency 'androidx.appcompat:appcompat-resources:1.6.1' requires libraries and applications that
      depend on it to compile against version 33 or later of the
      Android APIs.

      :app is currently compiled against android-32.

      Recommended action: Update this project to use a newer compileSdkVersion
      of at least 33, for example 33.

res/menu/my_toolbar.xml

メニューを Map3 から Map4 にコピーした。ここで使われているアイコンを Map3 から Map4 にコピーした。

MainActivity.java

メニューを表示するには、MainActivityにコードが必要である。

現段階では以下の通りである。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

レイアウト画面は setContentView(R.layout.activity_main) によって表示される。 ツールバーの表示方法は他にもあるかも知れないが、Map3 と同じ方法をとった。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.my_toolbar, menu);
        MenuCompat.setGroupDividerEnabled(menu, true);
        return true;
    }

}

ボタンやメニュー項目のタップに反応して、対応する処理を行うには、別途、コードが必要であるが、 その必要性が生じたときに追加する。

地図を表示する画面(キャンバス)を用意する

レイアウトに地図を表示する View を置く。コメントアウトしたものを有効に戻す。 class Mapに地図表示に関わるデータやコードが置かれる。

描画処理は onDraw に記述する。

public class Map extends View {
    public Map(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 描画処理
    }
}

最初のプログラム[2024.1.25]

だんだん複雑になるため、ここで、最初のプログラムを記載しておく。 プログラムは MainActivity と Map の二つだけである。

zoom は 18 で固定であるが、X、Y座標は指を動かせば変わり、画面中心のタイル座標を 画面左下に表示するようになっている。

OSMバイナリレコード形式を大幅に変更するため、メモリ使用量や処理時間を計測するための 下準備を行っている。

public class MainActivity extends AppCompatActivity {
    private Map map;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        map = findViewById(R.id.map_view);  // Mapインスタンス生成
        map.textViewBottom = findViewById(R.id.bottom_view);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.my_toolbar, menu);
        MenuCompat.setGroupDividerEnabled(menu, true);
        return true;
    }

}

public class Map extends View {

    TextView textViewTop, textViewBottom, ele_view, speed_view, copyright;

    static int PX = 256;                    // タイルの画素数
    int zoom = 18;
    int CX=(232825*PX), CY=(103226*PX);     // 地図中心タイル座標(単位:画素)
    private int currTX = -1,  currTY = -1;  // 地図中心タイル座標(単位:タイル)
    private int MarkX = -1, MarkY = -1;     // クライアントウィンドウ座標(画素単位)

    public Map(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 描画処理

        if (CX/PX != currTX || CY/PX != currTY) {
            String str = zoom + "_" + (currTX=CX/PX) + "_" + (currTY=CY/PX);
            textViewBottom.setText(str);
        }    // 画面中央のタイル座標を表示する
    }

    @Override
    public boolean onTouchEvent(MotionEvent motionEvent) {
        int eX = (int) motionEvent.getX();
        int eY = (int) motionEvent.getY();

        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                MarkX = eX;
                MarkY = eY;
                break;
            case MotionEvent.ACTION_MOVE:
                if (MarkX < 0) break;
                CX -= eX - MarkX;   // 指/マウスを動きに応じて
                CY -= eY - MarkY;   // 地図の中心座標を変更する
                MarkX = eX;
                MarkY = eY;
                break;
            case MotionEvent.ACTION_UP:
                MarkX = -1;
                MarkY = -1;
                break;
            default:
                return false;
        }
        invalidate();       // onDrawが呼び出される
        return true;
    }

}

アプリのメモリ使用量の表示

アプリの現在のメモリ使用量を表示するようにした。 現時点では 4MB であった。地図データはまだ一切ないため、当然の値である。

この後、OSMバイナリレコードなどを読み込んだ時、どれくらいの大きさになるかを調べる。

リファレンス