2018/02/16

BitmapDescriptorFactory.fromResource() で "IBitmapDescriptorFactory is not initialized" が起こる場合の対処方法

@play-services-maps:11.8.0

2017/07/07

タイルオーバーレイの x, y 座標を緯度・経度に変更する方法 (Google Maps Android API)

Google Maps Android API v2 では[タイル オーバーレイ](https://developers.google.com/maps/documentation/android-api/tileoverlay?hl=ja)が使えるようになり、独自の地図を重ねあわせたりするのに使えます。

2014/12/20

Google Maps Android API v2 の Marker は Drag 後に Position がアップデートされない

Google Maps Android API v2 では以下のようにドラッグ可能な Marker を作ることができます。

Marker marker = mGoogleMap.addMarker(
        new MarkerOptions()
                .position(location)
                .draggable(true));


GoogleMap クラスは Marker の情報を保存しておいてくれないので、上記のように作成した Marker のインスタンスは何らかの形で自分で保持しておかないといけないという制約があります。
ところが、Marker をドラッグ後に Marker#getPosition() を呼んでも、ドラッグ前の Position しか取得できません。 「ドラッグした」というイベントを捕まえて、自分で更新しないといけないようですちょっとイマイチな仕様だと思うのは私だけでしょうか…?


具体的には以下のような実装で、ドラッグ後のインスタンスに差し替えればよいかと思います。
// Marker を保持するための Map
private Map<String, Marker> mMarkers = new HashMap<>();

@Override
public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mMapView.getMapAsync(new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;

            // ドラッグ検知用のリスナ登録
            googleMap.setOnMarkerDragListener(mOnMarkerDragListener);

            // 地図上に Marker を表示し、mMarkers に保持する
            for (LatLng location : mLocations) {
                Marker marker = googleMap.addMarker(
                        new MarkerOptions()
                                .position(location)
                                .draggable(true));
                mMarkers.put(marker.getId(), marker);
            }
        }
    });
}

private final GoogleMap.OnMarkerDragListener mOnMarkerDragListener = 
        new GoogleMap.OnMarkerDragListener() {
    @Override
    public void onMarkerDragStart(Marker marker) {
    }

    @Override
    public void onMarkerDrag(Marker marker) {
    }

    @Override
    public void onMarkerDragEnd(Marker marker) {
        // ドラッグが終わったら、インスタンスを差し替える
        mMarkers.put(marker.getId(), marker);
    }
};


2010/11/20

Google Maps でダブルタップズーム for Android

Android で Map を扱うアプリを作っていると、デフォルトで入っている Google Map のようにダブルタップでズームして欲しいと思います。
ところが、なかなかこれが難しいのです。
調べてみると、皆さんなかなか苦労しているようです。

Android: MapActivityでダブルタップする (パトラッシュさん)

そこで、もう少しシンプルなやり方が無いか考えてみました。
ポイントは、onDoubleTapEvent ではなく onDoubleTap を使うことと、ZoomControl を連続タップした時にダブルタップとして認識されないようにする方法です。

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

import android.graphics.Rect;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.GestureDetector.OnGestureListener;

public class Main extends MapActivity implements OnGestureListener, OnDoubleTapListener {
    private MapView mapView;
    private GestureDetector gestureDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mapView = (MapView)findViewById(R.id.mapView01);
        mapView.setBuiltInZoomControls(true);

        gestureDetector = new GestureDetector(this, this);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent e) {
        super.dispatchTouchEvent(e);

        // ZoomController の 画面上の座標を取得する
        int[] offset = new int[2];
        mapView.getZoomButtonsController().getContainer().getLocationOnScreen(offset);
        // ZoomController 中の Hit領域の矩形を取得する
        // (Hitとは領域は + - が表示されている領域のこと)
        Rect rect = new Rect();
        mapView.getZoomButtonsController().getZoomControls().getHitRect(rect);
        // 画面上の座標に変換
        rect.offset(offset[0], offset[1]);
        if (!rect.contains((int)e.getRawX(), (int)e.getRawY())) {
            // タッチされた場所が、Hit領域に含まれていなければ
            gestureDetector.onTouchEvent(e);
        }

        return onTouchEvent(e);
    }

    public boolean onDoubleTap(MotionEvent e) {
        // ズーム処理
        mapView.getController().zoomInFixing((int)e.getX(), (int)e.getY());
        return true;
    }

    // ・・・
    // その他の 自動生成されたメソッド・スタブ に関しては省略

}

以下、簡単な解説です。