Android地图v2缩放以显示所有标记

我在GoogleMap有10个标记。 我想尽可能放大,并保持所有的标记在视图中? 在较早的版本中,这可以通过zoomToSpan()来实现,但是在v2中,我不知道如何做到这一点。 此外,我知道需要可见的圆的半径。

您应该使用CameraUpdate类(可能)执行所有程序化的地图移动。

为此,首先计算所有标记的界限,如下所示:

 LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (Marker marker : markers) { builder.include(marker.getPosition()); } LatLngBounds bounds = builder.build(); 

然后使用工厂获取移动描述对象: CameraUpdateFactory

 int padding = 0; // offset from edges of the map in pixels CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); 

最后移动地图:

 googleMap.moveCamera(cu); 

或者如果你想要一个animation:

 googleMap.animateCamera(cu); 

就这样 :)

澄清1

几乎所有的移动方法都要求Map对象通过布局过程。 您可以使用addOnGlobalLayoutListener构造等待发生这种情况。 详细信息可以在评论中find这个答案和其余的答案。 您也可以在这里使用addOnGlobalLayoutListenerfind设置地图范围的完整代码 。

澄清2

一个评论指出,只有一个标记使用这种方法导致地图缩放设置为“怪异”缩放级别(我相信这是给定位置可用的最大缩放级别)。 我认为这是预料之中的,因为:

  1. LatLngBounds bounds实例将具有等于southwest northeast属性,这意味着由这个bounds覆盖的地球部分恰好为零。 (这是合乎逻辑的,因为一个标记没有区域。)
  2. 通过传递给CameraUpdateFactory.newLatLngBounds bounds ,你基本上要求计算一个这样的缩放级别, bounds (有零区域)将覆盖整个地图视图。
  3. 你实际上可以在一张纸上进行这个计算。 作为答案的理论缩放级别是+∞(正无穷大)。 在实践中, Map对象不支持这个值,所以它被限制在给定位置允许的更合理的最大水平。

另一种说法是: Map对象如何知道单个位置应该select哪个缩放级别? 也许最佳值应该是20(如果它代表一个特定的地址)。 或者也许11(如果它代表一个城镇)。 或者也许6(如果它代表一个国家)。 API不是那么聪明,决定取决于你。

所以,你应该简单地检查markers是否只有一个位置,如果是的话,使用下面的一个:

  • CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition()) – 转到标记位置,保持当前缩放级别不变。
  • CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F) – 转到标记位置,将缩放级别设置为任意select的值12。

谷歌地图V2:放大MarkerOptions范围内最好的工作解决scheme为Android棉花糖6(API 23,API 24,API 25)以及在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); 

所以

我需要使用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 } }); 

我不能使用onGlobalLayoutlistener,所以这里是另一种解决scheme,以防止"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)); } }); 

为我工作得很好。

从这个代码,我在地图屏幕上显示具有特定缩放的多个标记。

//声明的variables

 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); 

– 这不是对原始问题的解决scheme。 这是上面讨论的其中一个子问题的解决scheme。

解决scheme@andr 澄清2

当边界上只有一个标记,并且由于缩放级别被设置为非常高的级别( 级别21 )时,它确实是有问题的。 而Google目前没有提供任何方式来设置最大缩放级别。 当有多于一个的标记时,这也可能发生,但是它们都非常接近。 那么也会出现同样的问题。

解决scheme – 假设您希望您的地图永远不会超出16倍缩放级别。 然后在做 –

 CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); mMap.moveCamera(cu); 

检查你的缩放级别是否超过了16级(或任何你想要的) –

 float currentZoom = mMap.getCameraPosition().zoom; 

如果这个级别大于16,那么只有在标记非常less或所有标记彼此非常接近的情况下,只要将缩放级别设置为16,就可以在特定位置缩小地图。

 mMap.moveCamera(CameraUpdateFactory.zoomTo(16)); 

这样你就永远不会有@andr的“怪异”缩放级别的问题。

使用“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(); } 

这将有助于..从谷歌apis演示

 private List<Marker> markerList = new ArrayList<>(); Marker marker = mGoogleMap.addMarker(new MarkerOptions().position(geoLatLng) .title(title)); markerList.add(marker); // Pan to see all markers in view. // Cannot zoom to bounds until the map has a size. final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView(); if (mapView!=null) { if (mapView.getViewTreeObserver().isAlive()) { mapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @SuppressWarnings("deprecation") // We use the new method when supported @SuppressLint("NewApi") // We check which build version we are using. @Override public void onGlobalLayout() { //Calculate the markers to get their position LatLngBounds.Builder b = new LatLngBounds.Builder(); for (Marker m : markerList) { b.include(m.getPosition()); } // also include current location to include in the view b.include(new LatLng(mLocation.getLatitude(),mLocation.getLongitude())); LatLngBounds bounds = b.build(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } }); } } 

为清楚的信息看这个URL。 https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/MarkerDemoActivity.java

我有类似的问题,使用下面的代码解决了这个问题:

CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5)通常在我的情况下,位置差异不超过两个邻居城市。

缩放以适应地图谷歌地图v2上的所有标记

  //For adding a marker in Google map MarkerOptions mp = new MarkerOptions(); mp.position(new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude))); mp.snippet(strAddress); map.addMarker(mp); try { b = new LatLngBounds.Builder(); if (MapDetailsList.list != null && MapDetailsList.list.size() > 0) { for (int i = 0; i < MapDetailsList.list.size(); i++) { b.include(new LatLng(Double.parseDouble(MapDetailsList.list.get(i).getLatitude()), Double.parseDouble(MapDetailsList.list.get(i).getLongitude()))); } LatLngBounds bounds = b.build(); DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); int width = displayMetrics.widthPixels; int height = displayMetrics.heightPixels; // Change the padding as per needed CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width-200, height-200, 5); // map.setCenter(bounds.getCenter()); map.animateCamera(cu); } } catch (Exception e) { } 

160wpb4.png

160wpb4.png

160wpb4.png