に 10 個のマーカーがありGoogleMap
ます。できるだけズームインして、すべてのマーカーを表示したいですか? 以前のバージョンではこれを実現できましたzoomToSpan()
が、v2 ではそれを行う方法がわかりません。さらに、表示する必要がある円の半径を知っています。
13 に答える
このCameraUpdate
クラスを使用して、(おそらく) すべてのプログラムによる地図の移動を行う必要があります。
これを行うには、まず次のようにすべてのマーカーの境界を計算します。
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
次に、 factory: を使用して移動記述オブジェクトを取得しますCameraUpdateFactory
。
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
最後にマップを移動します。
googleMap.moveCamera(cu);
または、アニメーションが必要な場合:
googleMap.animateCamera(cu);
それで全部です :)
明確化 1
ほとんどすべての移動方法では、Map
オブジェクトがレイアウト プロセスを通過する必要があります。addOnGlobalLayoutListener
コンストラクトを使用して、これが発生するのを待つことができます。詳細は、この回答と残りの回答へのコメントに記載されています。こちらを使用してマップ範囲を設定するaddOnGlobalLayoutListener
ための完全なコードを見つけることもできます。
明確化 2
1 つのコメントでは、この方法を 1 つのマーカーのみに使用すると、マップのズームが「奇妙な」ズーム レベル (特定の場所で利用可能な最大ズーム レベルであると私は信じています) に設定されます。これは予想されることだと思います。
LatLngBounds bounds
インスタンスは にnortheast
等しいプロパティを持ちます。これはsouthwest
、これによってカバーされる地球の面積の部分bounds
が正確にゼロであることを意味します。(単一のマーカーには領域がないため、これは論理的です。)- 渡す
bounds
ことで、マップ ビュー全体をカバーする (領域がゼロの)CameraUpdateFactory.newLatLngBounds
ズーム レベルの計算を基本的に要求します。bounds
- この計算は実際に紙の上で実行できます。答えである理論上のズーム レベルは +∞ (正の無限大) です。実際には、
Map
オブジェクトはこの値をサポートしていないため、特定の場所で許容されるより妥当な最大レベルにクランプされます。
別の言い方をすれば、単一の場所Map
に対してどのズーム レベルを選択する必要があるかをオブジェクトがどのように知ることができるでしょうか。おそらく、最適な値は 20 になるはずです (特定のアドレスを表す場合)。または、11 (町を表す場合) かもしれません。あるいは 6 (国を表す場合) かもしれません。API はそれほどスマートではなく、決定はあなた次第です。
markers
そのため、場所が 1 つしかないかどうかを確認し、その場合は次のいずれかを使用する必要があります。
CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition())
- マーカーの位置に移動し、現在のズーム レベルはそのままにします。CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F)
- マーカー位置に移動し、ズーム レベルを任意に選択した値 12 に設定します。
Google マップ V2
次のソリューションは、Android Marshmallow 6 (API 23、API 24、API 25、API 26、API 27、API 28) で機能します。Xamarin でも動作します。
LatLngBounds.Builder builder = new LatLngBounds.Builder();
//the include method will calculate the min and max bound.
builder.include(marker1.getPosition());
builder.include(marker2.getPosition());
builder.include(marker3.getPosition());
builder.include(marker4.getPosition());
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.10); // offset from edges of the map 10% of screen
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
mMap.animateCamera(cu);
onGlobalLayoutlistener を使用できなかったので、
"Map size can't be 0. Most likely, layout has not yet occured for the map view. Either wait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions."
エラーを防ぐ別の解決策を次に示します。
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 15));
}
});
そう
適切なサンプルを取得するには、 addOnGlobalLayoutListener を使用する必要がありました
たとえば、Google マップは RelativeLayout 内にあります。
RelativeLayout mapLayout = (RelativeLayout)findViewById(R.id.map_layout);
mapLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//and write code, which you can see in answer above
}
});
私のためにうまく働いています。
このコードから、マップ画面に特定のズームで複数のマーカーを表示しています。
// 宣言された変数
private LatLngBounds bounds;
private LatLngBounds.Builder builder;
// 描画可能なアイコンで複数のマーカー ポイントを追加するメソッド
private void drawMarker(LatLng point, String text) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point).title(text).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon));
mMap.addMarker(markerOptions);
builder.include(markerOptions.getPosition());
}
// マップ上に表示される複数のマーカーを追加するため
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
builder = new LatLngBounds.Builder();
for (int i = 0; i < locationList.size(); i++) {
drawMarker(new LatLng(Double.parseDouble(locationList.get(i).getLatitude()), Double.parseDouble(locationList.get(i).getLongitude())), locationList.get(i).getNo());
}
bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
mMap.animateCamera(cu);
注- これは元の質問に対する解決策ではありません。これは、上で説明したサブ問題の 1 つに対する解決策です。
@andr明確化 2の解決策-
境界内にマーカーが 1 つしかなく、そのためにズーム レベルが非常に高いレベル (レベル 21 ) に設定されている場合、これは非常に問題になります。また、Google は現時点で最大ズーム レベルを設定する方法を提供していません。これは、複数のマーカーがあり、それらがすべて互いに非常に近い場合にも発生する可能性があります。その後も同様の問題が発生します。
解決策- マップのズーム レベルが 16 を超えないようにしたいとします。それからやった後 -
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
mMap.moveCamera(cu);
ズームレベルがレベル16(または必要なもの)を超えているかどうかを確認します-
float currentZoom = mMap.getCameraPosition().zoom;
このレベルが 16 より大きい場合 (マーカーが非常に少ないか、すべてのマーカーが互いに非常に接近している場合のみ)、ズーム レベルを 16 に設定して、その特定の位置でのみマップをズームアウトします。
mMap.moveCamera(CameraUpdateFactory.zoomTo(16));
このようにして、@andr によって非常によく説明されている「奇妙な」ズームレベルの問題が発生することはありません。
すべてのマーカーを Google マップで表示
これらのメソッドでは、すべてのマーカーを保存し、自動的にズームしてすべてのマーカーを Google マップに表示します。
// Declare the Markers List.
List<MarkerOptions> markerList;
private BitmapDescriptor vnrPoint,banPoint;
public void storeAllMarkers()
{
markerList=new ArrayList<>();
markerList.removeAll(markerList);
// latitude and longitude of Virudhunagar
double latitude1=9.587209;
double longitude1=77.951431;
vnrPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_1);
LatLng vnr = new LatLng(latitude1, longitude1);
MarkerOptions vnrMarker = new MarkerOptions();
vnrMarker.position(vnr);
vnrMarker.icon(vnrPoint);
markerList.add(vnrMarker);
// latitude and longitude of Bengaluru
double latitude2=12.972442;
double longitude2=77.580643;
banPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_2);
LatLng ban = new LatLng(latitude2, longitude2);
MarkerOptions bengalureMarker = new MarkerOptions();
bengalureMarker.position(ban);
bengalureMarker.icon(banPoint);
markerList.add(bengalureMarker);
// You can add any numbers of MarkerOptions like this.
showAllMarkers();
}
public void showAllMarkers()
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions m : markerList) {
builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.30);
// Zoom and animate the google map to show all markers
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
googleMap.animateCamera(cu);
}
メソッド「getCenterCoordinate」を使用して中心座標を取得し、CameraPosition で使用します。
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setScrollGesturesEnabled(true);
mMap.getUiSettings().setTiltGesturesEnabled(true);
mMap.getUiSettings().setRotateGesturesEnabled(true);
clientMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_taxi))
);
clientMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location))
);
camPos = new CameraPosition.Builder()
.target(getCenterCoordinate())
.zoom(17)
.build();
camUpd3 = CameraUpdateFactory.newCameraPosition(camPos);
mMap.animateCamera(camUpd3);
}
public LatLng getCenterCoordinate(){
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)));
builder.include(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)));
LatLngBounds bounds = builder.build();
return bounds.getCenter();
}