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