26
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MapboxのAndroid SDKを少しだけ触ってみた

Last updated at Posted at 2016-04-06

MapboxのAndroid SDKを少しだけ触ってみました\(^o^)/

実装方法や使い方を触った範囲で書こうと思います。

Mapboxって何?

Mapboxは、簡単に言うとGoogle mapみたいなやつです(笑)
アプリやWebに簡単に地図を実装できます。
あと、地図上にマーカー置いたり線も引けたりできます。
今のところWeb, iOS, Androidなど一通りのプラットフォームで動くみたいです。

ちなみに、お値段は、こんな感じです。
https://www.mapbox.com/pricing/
スクリーンショット 2016-04-05 15.40.35.png

アカウント登録

Mapboxを使うには、はじめにアカウント登録する必要があります。
登録完了するとアクセストークンがもらえます。

トップページの右上らへんにログインする所あるので、ここからアカウント登録。
スクリーンショット 2016-04-05 15.44.12.png

登録が完了すると、こんな管理画面みたいなものが表示されると思うので、**「Access token」**の所にトークンがあると思うので、コピーします。

スクリーンショット 2016-04-05 15.44.53.png

AndroidでMapboxを使う

実際にAndroidアプリでMapBoxを使ってみます。(ライブラリは4.1.0を使用しています)

Gradle

GradleでMapboxのライブラリをいれます。

repositories {
    mavenCentral()
}

dependencies {
    compile ('com.mapbox.mapboxsdk:mapbox-android-sdk:4.0.0@aar'){
        transitive=true
    }
}

AndroidManifest

AndroidManifest.xmlに以下のpermissionと...


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

このserviceを入れます。


<service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService" />

全体は、こんな感じ。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="パッケージ名">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService" />

    </application>

</manifest>

activity_main.xml

MainActivity.javaとactivity_main.xmlの2つ用意してください。

activityのxmlにcom.mapbox.mapboxsdk.maps.MapViewを追加します。

activity_main.xml

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

    <com.mapbox.mapboxsdk.maps.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mapbox:access_token="アクセストークン"
        mapbox:style_url="@string/style_mapbox_streets"
        mapbox:center_latitude="33.590098"
        mapbox:center_longitude="130.419484"
        mapbox:zoom="15"/>

</RelativeLayout>

MainActivity.java

MainActivity.javaの方は、こんな感じです。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private MapView mapView;

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

        mapView = (MapView) findViewById(R.id.map_view);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(new OnMapReadyCallback() {
           @Override
           public void onMapReady(@NonNull final MapboxMap mapboxMap) {
              //地図読込完了...
           }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

}

これで、完了です。
実行すると、こんな感じに地図が表示されるはずです。

Screenshot_.png

ちなみに、この辺のxmlの設定は、


  mapbox:access_token="アクセストークン"
  mapbox:style_url="@string/style_mapbox_streets"
  mapbox:center_latitude="33.590098"
  mapbox:center_longitude="130.419484"
  mapbox:zoom="15"

こんな感じにJavaでも可能です。


  MapView mapView = (MapView) findViewById(R.id.map_view);
  mapView.setAccessToken("アクセストークン");
  mapView.setStyle(Style.MAPBOX_STREETS);
  mapView.getMapAsync(new OnMapReadyCallback() {
     @Override
     public void onMapReady(@NonNull MapboxMap mapboxMap) {
         mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
                 new CameraPosition.Builder()
                          .target(new LatLng(33.583549, 130.393819))
                          .zoom(14)
                          .bearing(0)
                          .tilt(0)
                          .build()));
     }
  });
       

Mapboxの機能

マーカー

こんなやつを表示させる方法です。

スクリーンショット 2016-04-06 11.25.24.png


mapView.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(@NonNull MapboxMap mapboxMap) {
        
        mapboxMap.addMarker(new MarkerOptions()
                .position(new LatLng(33.583549, 130.393819))
                .title("たいとる だよ")
                .snippet("すにぺっと"));

    }
});

マーカーの画像を変更する場合は、このようにします。


IconFactory iconFactory = IconFactory.getInstance(MainActivity.this);
Drawable iconDrawable = ContextCompat.getDrawable(MainActivity.this, R.drawable.icon);
Icon icon = iconFactory.fromDrawable(iconDrawable);

mapboxMap.addMarker(new MarkerOptions()
        .position(new LatLng(33.583549, 130.393819))
        .title("たいとる だよ")
        .snippet("すにぺっと")
        .icon(icon));

スクリーンショット 2016-04-06 11.27.33.png

マーカーをタップしたかの判定は、こんな感じみたいです。


mapboxMap.setOnMarkerClickListener(new MapboxMap.OnMarkerClickListener() {
   @Override
   public boolean onMarkerClick(@NonNull Marker marker) {
      Toast.makeText(getApplicationContext(), "マーカークリック: " + marker.getTitle(), Toast.LENGTH_LONG).show();
      return false;
   }
});

スクリーンショット 2016-04-06 11.28.47.png

地図上に線をひく方法は、これらしい。


mapView.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(@NonNull MapboxMap mapboxMap) {

        List<LatLng> line = new ArrayList<>();
        line.add(new LatLng(33.586319, 130.421886));
        line.add(new LatLng(33.590018, 130.374715));
      
        mapboxMap.addPolyline(new PolylineOptions().addAll(line));

    }
});

スクリーンショット 2016-04-06 11.30.45.png

色や太さも変更できるみたいです。

  mapboxMap.addPolyline(new PolylineOptions().addAll(line).width(1).color(Color.BLUE));

スクリーンショット 2016-04-06 11.31.00.png

オフライン使用

事前に地図をダウンロードしておくことで、オフラインになった時でも利用できるみたいです。

public class MainActivity extends AppCompatActivity {

    private MapView mapView;

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

        mapView = (MapView) findViewById(R.id.map_view);
        mapView.setAccessToken("アクセストークン");
        mapView.setStyle(Style.MAPBOX_STREETS);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(@NonNull final MapboxMap mapboxMap) {
                mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
                        new CameraPosition.Builder()
                                .target(new LatLng(33.583549, 130.393819))
                                .zoom(14)
                                .bearing(0)
                                .tilt(0)
                                .build()));
            }
        });

        OfflineManager mOfflineManager = OfflineManager.getInstance(this);
        mOfflineManager.setAccessToken("アクセストークン");

        LatLngBounds latLngBounds = new LatLngBounds.Builder()
                .include(new LatLng(33.597793, 130.431185))
                .include(new LatLng(33.576200, 130.406466))
                .build();

        OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
                mapView.getStyleUrl(), latLngBounds, 10, 20, this.getResources().getDisplayMetrics().density);

        byte[] metadata;
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("FIELD_REGION_NAME", "Fukuoka");
            String json = jsonObject.toString();
            metadata = json.getBytes("UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            metadata = null;
        }

        mOfflineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() {
            @Override
            public void onCreate(OfflineRegion offlineRegion) {
                offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);

                offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() {
                    @Override
                    public void onStatusChanged(OfflineRegionStatus status) {
                        //進捗
                        double percentage = status.getRequiredResourceCount() >= 0 ?
                                (100.0 * status.getCompletedResourceCount() / status.getRequiredResourceCount()) :
                                0.0;

                        if (status.isComplete()) {
                            //ダウンロード完了
                            return;
                        }

                    }

                    @Override
                    public void onError(OfflineRegionError error) {
                        //エラー
                    }

                    @Override
                    public void mapboxTileCountLimitExceeded(long limit) {

                    }
                });

            }

            @Override
            public void onError(String error) {
                //エラー
            }
        });

    }

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

}

オフラインになったら自動で切り替わるみたいです。
ちなみにこのデータはmbgl-offline.dbに保存されてるみたいです。

あ!
こちらのmetadataを使うと、ダウンロードした地図と一緒に別の値を保存することができます。

byte[] metadata;
try {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("FIELD_REGION_NAME", "Fukuoka");
    String json = jsonObject.toString();
    metadata = json.getBytes("UTF-8");
} catch (Exception e) {
    e.printStackTrace();
    metadata = null;
}

ここでは、jsonの形で「Fukuoka」という値をいれています。(別にjsonでする必要はないです)
地図の名前やIDなど、そういったものに使うと良いと思います。

で、指定したmetadataは、**offlineRegion.getMetadata()**で取得できます。


mOfflineManager.listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
    @Override
    public void onList(OfflineRegion[] offlineRegions) {
       if (offlineRegions == null || offlineRegions.length == 0) {
            return;
       }

       for (OfflineRegion offlineRegion : offlineRegions) {
            //metadata取得
            offlineRegion.getMetadata();
       }
   }

   @Override
   public void onError(String error) {
     //エラー
   }
});

まとめ

ただ地図を表示するくらいなら、Mapboxでも良いかも。
個人的にはMapboxの地図のデザインはGoogle mapより好き(笑)

ライブラリが頻繁に更新されているみたいで、仕様変更がよくあるらしい。。。

ちなみに、Mapboxのサンプル集は、こちらです。
https://github.com/mapbox/mapbox-gl-native/tree/11f7db293e5488690b87ee0260f910e49e5e0275/platform/android/MapboxGLAndroidSDKTestApp

26
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?