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

スポンサーリンク
LINEで送る
Pocket

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の見直しを行います。

LINEで送る
Pocket

タイトルとURLをコピーしました