マーカー

マーカーは、地図上の単一の場所を示します。マーカーは、デフォルトの色を変更したり、マーカー アイコンをカスタム画像に置き換えたりしてカスタマイズすることができます。情報ウィンドウを使用して、マーカーの追加情報を提供することもできます。

コードサンプル

GitHub の ApiDemos リポジトリには、各種のマーカーの機能を示すサンプルが含まれています。

はじめに

マーカーは、地図上の場所を表します。デフォルトのマーカーでは、Google マップのデザインに共通の、標準のアイコンが使用されます。API で、アイコンの色、画像、アンカー ポイントを変更することもできます。マーカーは Marker というタイプのオブジェクトで、GoogleMap.addMarker(markerOptions) メソッドで地図に追加されます。

マーカーは、インタラクティブに動作するように設計されています。これらはデフォルトで click イベントを受け取り、多くの場合は情報ウィンドウを起動するためのイベント リスナーとともに使用されます。マーカーの draggable プロパティを true に設定すると、ユーザーがマーカーの位置を変更できるようになります。長押しすると、マーカーを移動する機能がアクティブになります。

デフォルトでは、ユーザーがマーカーをタップすると、地図の右下にマップ ツールバーが表示され、Google マップ モバイルアプリに簡単にアクセスできるようになります。このツールバーは無効にすることもできます。詳しくは、コントロールに関するガイドをご覧ください。

マーカーのスタートガイド

この Maps Live のエピソードでは、Maps SDK for Android を使って地図にマーカーを追加するための基本について説明します。

マーカーを追加する

地図にマーカーを追加する方法について、次に例を示します。マーカーは座標 10,10 に設定されます。このマーカーをクリックすると、情報ウィンドウに「Hello world」という文字列が表示されます。

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(10, 10))
        .title("Hello world"));
}

マーカーの追加情報を表示する

通常では、地図上のマーカーをタップしたユーザーに、お店やスポットなどの場所に関する追加情報を表示する必要があります。情報ウィンドウに関するガイドをご覧ください。

マーカーにデータを関連付ける

次のコードサンプルに示すように、マーカーを含む任意のデータ オブジェクトを保存するには Marker.setTag() を使用し、データ オブジェクトを取得するには Marker.getTag() を使用します。

/**
 * A demo class that stores and retrieves data objects with each marker.
 */
public class MarkerDemoActivity extends FragmentActivity implements
        OnMarkerClickListener,
        OnMapReadyCallback {

    private static final LatLng PERTH = new LatLng(-31.952854, 115.857342);
    private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
    private static final LatLng BRISBANE = new LatLng(-27.47093, 153.0235);

    private Marker mPerth;
    private Marker mSydney;
    private Marker mBrisbane;

    private GoogleMap mMap;

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

        SupportMapFragment mapFragment =
                (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    /** Called when the map is ready. */
    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;

        // Add some markers to the map, and add a data object to each marker.
        mPerth = mMap.addMarker(new MarkerOptions()
                .position(PERTH)
                .title("Perth"));
        mPerth.setTag(0);

        mSydney = mMap.addMarker(new MarkerOptions()
                .position(SYDNEY)
                .title("Sydney"));
        mSydney.setTag(0);

        mBrisbane = mMap.addMarker(new MarkerOptions()
                .position(BRISBANE)
                .title("Brisbane"));
        mBrisbane.setTag(0);

        // Set a listener for marker click.
        mMap.setOnMarkerClickListener(this);
    }

    /** Called when the user clicks a marker. */
    @Override
    public boolean onMarkerClick(final Marker marker) {

        // Retrieve the data from the marker.
        Integer clickCount = (Integer) marker.getTag();

        // Check if a click count was set, then display the click count.
        if (clickCount != null) {
            clickCount = clickCount + 1;
            marker.setTag(clickCount);
            Toast.makeText(this,
                           marker.getTitle() +
                           " has been clicked " + clickCount + " times.",
                           Toast.LENGTH_SHORT).show();
        }

        // Return false to indicate that we have not consumed the event and that we wish
        // for the default behavior to occur (which is for the camera to move such that the
        // marker is centered and for the marker's info window to open, if it has one).
        return false;
    }
}

マーカーでデータを保存および取得する方法が有用なシナリオの例を、次にいくつか紹介します。

  • アプリで複数のタイプのマーカーを提供し、それぞれがクリックされたときに異なった処理が行われるようにしたい場合。そのためには、タイプを示す String をマーカーに保存します。
  • 一意の記録識別子を使用するシステムと連携し、そのシステムの記録をマーカーとして表示する場合。
  • マーカーデータによって、マーカーの Z-Index の優先順位が決まる場合。

マーカーをドラッグ可能にする

マーカーの draggable プロパティを true に設定しておくと、マップに追加されたマーカーの位置を変更できます。マーカーを長押しすると、ドラッグが有効になります。画面から指を離すと、マーカーがその位置に固定されます。

デフォルトでは、マーカーはドラッグできません。マーカーを明示的にドラッグ可能に設定するには、地図に追加する前に MarkerOptions.draggable(boolean) を使用するか、地図に追加した後で Marker.setDraggable(boolean) を使用する必要があります。マーカーでは、マーカー ドラッグ イベントで説明しているように、ドラッグ イベントをリッスンできます。

以下のスニペットでは、オーストラリアのパースにドラッグ可能なマーカーが追加されます。

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .draggable(true));

マーカーをカスタマイズする

次の動画では、マーカーを使用して地図上の場所を視覚化する方法を紹介しています。

マーカーでは、デフォルトのアイコンの代わりに表示するカスタム画像を定義できます。 アイコンを定義する際は、マーカーの視覚的な動作を制御するさまざまなプロパティを設定する必要があります。

マーカーでは、次のプロパティを使用したカスタマイズがサポートされています。

position(必須)
地図上のマーカーの位置を表す LatLng 値。これは、Marker オブジェクトで唯一の必須プロパティです。
anchor
マーカーの LatLng の位置に配置される画像上の点。デフォルトでは、画像下部の中央に設定されます。
alpha
マーカーの不透明度を設定します。デフォルトでは 1.0 に設定されます。
title
ユーザーがマーカーをタップしたときに、情報ウィンドウに表示される文字列。
snippet
タイトルの下に表示される追加のテキスト。
icon
デフォルトのマーカー画像の代わりに表示されるビットマップ。
draggable
ユーザーがマーカーを移動できるようにしたい場合は、true に設定します。デフォルトでは false に設定されます。
visible
マーカーを非表示にするには、false に設定します。デフォルトでは true に設定されます。
flat(ビルボードの向き)
デフォルトでは、マーカーは画面の向きに合わせて表示され、カメラの動きに合わせて回転または傾斜することはありません。一方、フラット マーカーは地面の向きに合わせて表示され、カメラの動きに合わせて回転または傾斜します。どちらのタイプのマーカーも、ズームによってサイズが変わることはありません。この効果が必要な場合は、GroundOverlays を使用してください。
rotation
時計回りの角度で指定される、マーカーの向き。マーカーがフラットの場合は、デフォルトの位置が変わります。フラット マーカーのデフォルトの位置は北向きです。マーカーがフラットではない場合、デフォルトの位置は上向きとなり、マーカーは常にカメラの方を向いて回転します。

以下のスニペットでは、デフォルト アイコンを使用する単純なマーカーが作成されます。

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE));

マーカーの色をカスタマイズする

デフォルトのマーカー画像の色は、BitmapDescriptor オブジェクトを icon() メソッドに渡してカスタマイズすることが可能です。BitmapDescriptorFactory オブジェクトで事前定義されている色のセットを使用するか、BitmapDescriptorFactory.defaultMarker(float hue) メソッドでカスタム マーカーの色を設定することが可能です。hue は 0 から 360 までの値で、色相環上の点を表します。

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE)
                          .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));

マーカーの不透明度をカスタマイズする

マーカーの不透明度を調整するには、MarkerOptions.alpha() メソッドを使用します。 alpha は 0.0 から 1.0 までの浮動小数で指定する必要があります。0 は完全な透明を表し、1 は完全な不透明を表します。

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE)
                          .alpha(0.7f));

マーカー画像をカスタマイズする

デフォルトのマーカー画像は、カスタム マーカー画像(通常はアイコンと呼ばれます)で置き換えることができます。カスタム アイコンは常に BitmapDescriptor として定義され、BitmapDescriptorFactory クラスのいずれかのメソッドで定義されます。

fromAsset(String assetName)
assets ディレクトリに含まれるビットマップ画像の名前を使用してカスタム マーカーを作成します。
fromBitmap(Bitmap image)
ビットマップ画像からカスタム マーカーを作成します。
fromFile(String fileName)
内部ストレージにあるビットマップ画像ファイルの名前を使用してカスタム アイコンを作成します。
fromPath(String absolutePath)
ビットマップ画像の絶対ファイルパスからカスタム マーカーを作成します。
fromResource(int resourceId)
ビットマップ画像のリソース ID を使用してカスタム マーカーを作成します。

以下のスニペットでは、カスタム アイコンを持つマーカーが作成されます。

  private static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
  private Marker melbourne = mMap.addMarker(new MarkerOptions()
                            .position(MELBOURNE)
                            .title("Melbourne")
                            .snippet("Population: 4,137,400")
                            .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));

マーカーをフラットにする

マーカー アイコンは、通常は画面に合わせて表示され、地図を回転、傾斜、ズームしてもマーカーの向きが変わることはありません。マーカーの向きは、地面に合わせて表示されるように設定することもできます。この方法で向きを設定したマーカーは、地図が回転すると回り、地図が傾斜すると角度が変わります。地図を拡大または縮小しても、フラット マーカーのサイズは変わりません。

マーカーの向きを変えるには、マーカーの flat プロパティを true に設定します。

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .flat(true));

マーカーを回転する

アンカー ポイントを中心としてマーカーを回転させるには、Marker.setRotation() メソッドを使用します。回転は、デフォルトの位置からの時計回りの度数で指定します。地図上のマーカーがフラットな場合、デフォルトの位置は北となります。フラットではないマーカーの場合、デフォルトの位置は上向きとなり、マーカーは常にカメラの方を向いて回転します。

次の例では、マーカーが 90° 回転します。アンカー ポイントを 0.5,0.5 に設定すると、マーカーは基部ではなく中心を軸にして回転します。

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .anchor(0.5,0.5)
                          .rotation(90.0));

マーカーの Z-Index

Z-Index では、該当のマーカーの積み重ね順を、地図上の他のマーカーとの相対値で指定します。Z-Index が高いマーカーは、Z-Index がより低いマーカーの上に表示されます。デフォルトの ZIndex 値は 0 です。

マーカーのオプションのオブジェクトに Z-Index を設定するには、次のコード スニペットに示すように MarkerOptions.zIndex() を呼び出します。

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(10, 10))
        .title("Marker z1")
        .zIndex(1.0f));
}

マーカーの Z-Index にアクセスするには Marker.getZIndex() を呼び出し、Z-Index を変更するには Marker.setZIndex() を呼び出します。

マーカーは、他のオーバーレイの Z-Index に関係なく、常にタイルレイヤおよびその他のマーカー以外のオーバーレイ(地面オーバーレイ、ポリライン、ポリゴン、その他のシェイプ)の上に表示されます。マーカーは、実質的に、他のオーバーレイとは異なる Z-Index グループに属していると見なされます。

詳しくは、以下のクリック イベントでの Z-Index の効果をご覧ください。

マーカー イベントを処理する

Maps API を使用すると、マーカー イベントをリッスンして、応答できます。これらのイベントをリッスンするには、マーカーが属している GoogleMap オブジェクトに、対応するリスナーを設定する必要があります。地図上のいずれかのマーカーでイベントが発生すると、対応する Marker オブジェクトがパラメータとして渡され、リスナーのコールバックが呼び出されます。この Marker オブジェクトを、Marker オブジェクトに対する独自の参照と比較するには、== ではなく equals() を使用する必要があります。

次のイベントをリッスンできます。

マーカーのクリック イベント

マーカーでのクリック イベントをリッスンするには、OnMarkerClickListener を使用します。このリスナーを地図に設定するには、GoogleMap.setOnMarkerClickListener(OnMarkerClickListener) を呼び出します。ユーザーがマーカーをクリックすると、onMarkerClick(Marker) が呼び出され、マーカーが引数として渡されます。このメソッドは、イベントが独自に処理されたかどうか(たとえばデフォルトの動作が行われないようにしたい場合など)を示すブール値を返します。false が返された場合は、カスタムの動作に加えてデフォルトの動作が行われます。マーカーのクリック イベントでは、デフォルトの動作として、そのマーカーの情報ウィンドウ(表示可能な場合)が表示され、マーカーが地図の中心に表示されるようカメラが移動します。

クリック イベントでの Z-Index の効果:

  • ユーザーがマーカーのクラスタをクリックすると、Z-Index が最も高いマーカーでクリック イベントがトリガーされます。
  • 1 回のクリックにつき最大 1 つのイベントがトリガーされます。つまり、Z-Index 値がより低いマーカーまたはその他のオーバーレイには、クリックが渡されません。
  • マーカーのクラスタをクリックすると、それ以降のクリックが他のマーカー間を循環し、各マーカーが順番に選択されます。循環の優先順位として、まず Z-Iindex の高い順に選択され、次にクリックされた地点に近い順に選択されます。
  • クラスタの周辺以外の場所をクリックすると、API でクラスタが再計算されてクリックの循環ステータスがリセットされ、循環が最初から始まるようになります。
  • クリック イベントは、マーカーのクラスタを一巡すると、その他のシェイプおよびオーバーレイが対象となり、その後クラスタ内を再度循環します。
  • マーカーは、他のオーバーレイの Z-Index に関係なく、他のオーバーレイまたはシェイプ(ポリライン、ポリゴン、円、地面オーバーレイ)とは異なる Z-Index グループに属していると見なされます。複数のマーカーやオーバーレイ、またはシェイプが重なって表示されている場合、クリック イベントは、まずマーカーのクラスタを循環してから、Z-Index 値に基づいて他のクリック可能なオーバーレイまたはシェイプでトリガーされます。

マーカーのドラッグ イベント

マーカーでのドラッグ イベントをリッスンするには、OnMarkerDragListener を使用します。このリスナーを地図に設定するには、GoogleMap.setOnMarkerDragListener を呼び出します。マーカーをドラッグするには、そのマーカーを長押しします。画面から指を離すと、マーカーがその位置に固定されます。マーカーをドラッグすると、最初に onMarkerDragStart(Marker) が呼び出されます。マーカーをドラッグしている間は、onMarkerDrag(Marker) が継続して呼び出されます。ドラッグが終了すると、onMarkerDragEnd(Marker) が呼び出されます。マーカーの位置を取得するには、随時 Marker.getPosition() を呼び出します。