googleMap第3回 マークと直線 | Marker and Polyline | Android

スポンサーリンク

AndroidでGoogleMapアプリ作成

第1回 表示
第2回 表示形式 衛星、地図、地形図
第3回 マーカーと直線
第4回 googleMapのエラー
第5回 PlaceAPIとマーカーのセット
第6回 現在地 GPSの実装
第7回 トラッキング
第8回 様々な技法

引き続き前回と同じプロジェクトを利用します。

スポンサーリンク

マーカーをつける

まずは富士山山頂にマーカーをつけることからはじめます。見やすさのためにズームレベルも若干下げます。

mMap.addMarker(new MarkerOptions()
    .position(targetLatLng)
    .icon(BitmapDescriptorFactory
    .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
cameraPosition = new CameraPosition.Builder()
    .target(targetLatLng).zoom(mMap.getMaxZoomLevel()-6)
    .build();
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

addMarkerを用います。positionで場所を指定し、マーカーのアイコンはデフォルトの形の黄色いマーカーを指定しています。ズームレベルについては -6 に変更しました。またbearingの設定を通常通り戻しています。

マークがつきました。マークをタップすると右下にルート検索や地図マークが出ます。

直線を引く

直線を引くために、もう1地点用意します。今回は静岡県の富士市役所とします。

double fujiCityHallLatDouble = 35.161426;
double fujiCityHallLngDouble = 138.676222;
LatLng startLatLng= new LatLng(fujiCityHallLatDouble ,fujiCityHallLngDouble );

startLatLngからtargetLatLngまで直線を引くことになります。

mMap.addMarker(new MarkerOptions()
    .position(targetLatLng)
    .icon(BitmapDescriptorFactory
    .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
mMap.addPolyline(new PolylineOptions()
    .add(startLatLng, targetLatLng)
    .width(7)
    .color(getResources().getColor(R.color.colorPrimary)));
mMap.addMarker(new MarkerOptions()
    .position(startLatLng)
    .icon(BitmapDescriptorFactory
    .defaultMarker(BitmapDescriptorFactory.HUE_RED)));

addPolylineで直線をマップに描画します。その設定についてはPolylineOptionsでおこなっています。そのまま、という感じで難しくはないのではないでしょうか。

マーカーを移動可能にする

黄色いマーカーを移動可能にします。表示中のマーカーを消して新しくマークをする。という形となります。

まずはマーカーを追加

mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng latLng) {
        mMap.addMarker(new MarkerOptions()
            .position(latLng)
            .icon(BitmapDescriptorFactory
            .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
    }
});

マップのリスナーが緯度経度を取得してその場所にマーカーを付けます。新たに付けていますからマーカーは消えません。

では、消すにはどうしたらよいでしょうか。markerをインスタンス化してHashMapで管理します。

java.util.Set<Marker> mMarker = new java.util.HashSet<>();
Marker marker;

とし、

marker = mMap.addMarker(new MarkerOptions()
                .position(targetLatLng)
                .icon(BitmapDescriptorFactory
                .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
        mMarker.add(marker);

として登録していきます。その上でマップタップに関するリスナーを使います。

mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng latLng) {
        java.util.Iterator<Marker> markerIterator = mMarker.iterator();
        while (markerIterator.hasNext()) {
            Marker markerIte = markerIterator.next();
            markerIte.remove();
            markerIterator.remove();
         }
         marker=mMap.addMarker(new MarkerOptions()
             .position(latLng)
             .icon(BitmapDescriptorFactory
              .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
         mMarker.add(marker);
    }
});

イテレータを使ってマーカーを削除しています。そのうえで新しい地点についてマーカーを表示しています。赤いマーカーは登録していませんから削除はされません。

直線を追従させる場合もイテレータを使ってまったく同じように記述します。

サンプルコード

startLatLngをカメラの中心地点として設定しています。

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
    GoogleMap mMap;
    double mtFujiLatDouble = 35.360556;
    double mtFujiLngDouble = 138.727778;
    LatLng targetLatLng= new LatLng(mtFujiLatDouble ,mtFujiLngDouble );
    double fujiCityHallLatDouble = 35.161426;
    double fujiCityHallLngDouble = 138.676222;
    LatLng startLatLng= new LatLng(fujiCityHallLatDouble ,fujiCityHallLngDouble );

    Marker marker;
    java.util.Set<Marker> mMarker = new java.util.HashSet<>();
    Polyline line;
    java.util.Set<Polyline> mLine = new java.util.HashSet<>();

    CameraPosition cameraPosition;
    Button mapTypeButton;
    int mapTypeFlagInt;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mapTypeButton = (Button) findViewById(R.id.mapTypeButton);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        marker = mMap.addMarker(new MarkerOptions()
                .position(targetLatLng)
                .icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
        mMarker.add(marker);
        
        line = mMap.addPolyline(new PolylineOptions()
                .add(startLatLng, targetLatLng)
                .width(7)
                .color(getResources().getColor(R.color.colorPrimary)));
        mLine.add(line);

        mMap.addMarker(new MarkerOptions()
                .position(startLatLng)
                .icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        cameraPosition = new CameraPosition.Builder()
                .target(startLatLng).zoom(mMap.getMaxZoomLevel()-10)
                .build();
        mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {

                java.util.Iterator<Marker> markerIterator = mMarker.iterator();
                while (markerIterator.hasNext()) {
                    Marker markerI = markerIterator.next();
                    markerI.remove();
                    markerIterator.remove();
                }
                java.util.Iterator<Polyline> polylineIterator = mLine.iterator();
                while (polylineIterator.hasNext()) {
                    Polyline polyline = polylineIterator.next();
                    polyline.remove();
                    polylineIterator.remove();
                }
                marker=mMap.addMarker(new MarkerOptions()
                        .position(latLng)
                        .icon(BitmapDescriptorFactory
                                .defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
                line= mMap.addPolyline(new PolylineOptions()
                                .add(startLatLng, latLng)
                                .width(7)
                                .color(getResources().getColor(R.color.colorPrimary)));
                mMarker.add(marker);
                mLine.add(line);
            }
        });
        mapTypeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mapTypeFlagInt++;
                if (mapTypeFlagInt == 4) mapTypeFlagInt = 0;
                setMapType(mapTypeFlagInt);
            }
        });
    }
    public void setMapType(int mapType){
        switch (mapType) {
            case 0:
                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                break;
            case 1:
                mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                break;
            case 2:
                mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
                break;
            case 3:
                mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
                break;
        }
    }
}

特にmapのリスナーの中身については実際は別途メソッドにしたりするべきですが、今回は見やすさのため上記のようなコードとしました。

次回はエラーが発生するケースやその対処法、及びManifestの見直しを行います。