【osmdroid】Android でマップを表示する(Java)

はじめに

 地図を使った Android アプリを開発するとき、真っ先に浮かぶのが Google Maps です。しかし Google Maps は従量課金制となっており、アクセス数が多くなるほど課金が必要になっています。

 そこで、Google Maps の代替手段となるのが osmdroid です。osmdroid は Android 上で OpenStreetMap を使えるようにしたライブラリで、基本的には無償で使用することができます。というのも、この OpenStreetMap が「誰でも自由に地図を編集して、誰でも自由に地図を利用使えるように」という世界的プロジェクトで、いわば地図界のWikipediaにあたるような存在です。各個人が GPS などでデータを集めていき、共有することで、非常に詳細なマップのデータベースを作り上げています。もちろん、無限に OpenStreetMap のサーバーにアクセスしていい訳では無いのですが、例えば OpenStreetMap のマップデータをレンタルサーバーに保存しておき(複製可)、そのサーバーに osmdroid でアクセスするようにすれば、特に利用料を気にせずに Android アプリを開発することが出来ます。
 
 今回はそんな osmdroid について、導入方法を説明したいと思います。

osmdroid の導入方法

 導入方法ですが、まず Android Studio で「File」→「New」→「New Project」で、新しい Empty Activity を作成します。この例では、プロジェクト名を「TrekkingTrail」としました。
 次に、build.gradle (:app) に、下記を追記します。

dependencies {
    ...
    implementation 'org.osmdroid:osmdroid-android:6.1.13' // この行を追加
    ...
}

追記後、「Sync Now」を実行します。
 同期が終了したら、AndroidManifest.xml に、permission を追加します。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

permission 追加後の AndroidManifest.xml は以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <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:supportsRtl="true"
        android:theme="@style/Theme.TrekkingTrail"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

これで、osmdroid を使う準備が完了です。
 activity_main.xml に MapView を追加します。

<org.osmdroid.views.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

画面いっぱいにマップを表示する場合、activity_main.xml の例は以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <org.osmdroid.views.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

 最後に、MainActivity.java に以下のように記載します。

package com.example.trekkingtrail;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.preference.PreferenceManager;
import org.osmdroid.config.Configuration;
import org.osmdroid.views.MapView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Configuration.getInstance().load(getApplicationContext(),
                PreferenceManager.getDefaultSharedPreferences(getApplicationContext())); // 追記(setContentView より前に置く)
        setContentView(R.layout.activity_main);
    }
}

アプリをダウンロードすると、マップが表示されることが確認できます。

図1. osmdroid 導入画面

マップの初期設定をする

 以上のようにマップを表示することは出来ましたが、ズームレベルの初期値が0になっているため、小さな世界地図が表示されています。そこで、初期値の中心座標とズームレベルを設定します。
 MainActivity.java に以下のように追記します。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Configuration.getInstance().load(getApplicationContext(),
                PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
        setContentView(R.layout.activity_main);

        MapView mapView = (MapView) findViewById(R.id.mapView);
        IMapController mapController =  mapView.getController();
        mapController.setZoom( 6.0 );         // ズームレベルの設定
        GeoPoint centerPoint = new GeoPoint( 38.00, 138.00 );
        mapController.setCenter(centerPoint); // 中心座標の設定

        mapView.setMultiTouchControls(true);  // タップでズームの追加

        mapView.setHorizontalMapRepetitionEnabled(true);      // 地球一周してもマーカー等のオブジェクトを繰り返す
        mapView.setVerticalMapRepetitionEnabled(false);       // 南北方向に一周した場合はオブジェクトを繰り返さない
        mapView.setScrollableAreaLimitLatitude(MapView.getTileSystem().getMaxLatitude(),
                MapView.getTileSystem().getMinLatitude(), 0); // 南北方向のスクロール範囲を北極から南極までに制限する
        mapView.setMinZoomLevel(3.0);                         // 最小ズームレベルを3に設定する
    }
}

 初期値の中心座標とズームレベルが設定されたのが確認できました。

図2. 初期位置の設定

デモアプリ

 当サイトでは、osmdroid を用いた GPS ロガーのデモアプリを公開しています。使い方はこちら。下記のボタン、あるいはQRコードよりダウンロードできます。このアプリは Android4.1 から Android13 までに対応しています。
 

 


備考:デモアプリの Google Play での公開はめんどくさすぎて心が折れました。
 なお、デモアプリ上で使用しているマップデータは当サイトのサーバーに保存しているため、サーバースペックにより低解像度の地図となっています。高解像度な地図をご所望の方は、こちらにソースコードを公開しているので、Android Studio でアプリを作成して、OpenStreetMap にアクセスしてください。
 機種によってはバッテリー消費を抑える為、アプリが強制停止されることがあります。その場合は、バッテリー設定より、バックグラウンドでの動作を常に許可してください。
 → プライバシーポリシー

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です