在谷歌地图android api v2中设置最大缩放级别
我目前正在使用Google maps android API v2开发应用程序。 我的代码如下。 假设地图有几个标记,并放大显示所有标记。
LatLngBuilder.Builder builder = LatLngBounds.builder(); for(Marker m : markers){ builder.include(m.getPosition()); } LatLngBounds bounds = builder.build(); map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10);
此代码工作正常,但我想停止animation时缩放级别达到17.0f; 看来地图API没有这样的方法来控制缩放级别。 有谁知道解决这个问题的任何想法?
我还没有在Google Maps API中find任何直接的解决scheme。 这个问题的一个可能的解决scheme在于侦听OnCameraChange事件 :当这个事件触发,缩放级别高于最大缩放级别时,可以调用animateCamera() 。 结果代码如下:
@Override public void onCameraChange(CameraPosition position) { float maxZoom = 17.0f; if (position.zoom > maxZoom) map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom)); }
Google地图API的最新更新介绍了您需要的function:
GoogleMap.setMaxZoomPreference() GoogleMap.setMinZoomPreference()
尽pipe如此,它仍然不妨碍播放animation。
下面是Arvis的解决scheme对应的Java代码,对我来说效果很好:
private LatLngBounds adjustBoundsForMaxZoomLevel(LatLngBounds bounds) { LatLng sw = bounds.southwest; LatLng ne = bounds.northeast; double deltaLat = Math.abs(sw.latitude - ne.latitude); double deltaLon = Math.abs(sw.longitude - ne.longitude); final double zoomN = 0.005; // minimum zoom coefficient if (deltaLat < zoomN) { sw = new LatLng(sw.latitude - (zoomN - deltaLat / 2), sw.longitude); ne = new LatLng(ne.latitude + (zoomN - deltaLat / 2), ne.longitude); bounds = new LatLngBounds(sw, ne); } else if (deltaLon < zoomN) { sw = new LatLng(sw.latitude, sw.longitude - (zoomN - deltaLon / 2)); ne = new LatLng(ne.latitude, ne.longitude + (zoomN - deltaLon / 2)); bounds = new LatLngBounds(sw, ne); } return bounds; }
从Android文档: https : //developers.google.com/maps/documentation/android-api/views
You may find it useful to set a prefered minimum and/or maximum zoom level. For example, this is useful to control the user's experience if your app shows a defined area around a point of interest, or if you're using a custom tile overlay with a limited set of zoom levels.
private GoogleMap mMap; // Set a preference for minimum and maximum zoom. mMap.setMinZoomPreference(6.0f); mMap.setMaxZoomPreference(14.0f);
与Arvis解决scheme相同,但使用Location
[ distanceBetween()
]( http://developer.android.com/reference/android/location/Location.html#distanceBetween (double,double,double,double,float []))方法计算到点之间的距离:
@Override public void zoomToMarkers(Set<Marker> markers) { LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (Marker marker : markers) { builder.include(marker.getPosition()); } LatLngBounds bounds = builder.build(); // Calculate distance between northeast and southwest float[] results = new float[1]; android.location.Location.distanceBetween(bounds.northeast.latitude, bounds.northeast.longitude, bounds.southwest.latitude, bounds.southwest.longitude, results); CameraUpdate cu = null; if (results[0] < 1000) { // distance is less than 1 km -> set to zoom level 15 cu = CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 15); } else { int padding = 50; // offset from edges of the map in pixels cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); } if (cu != null) { mMap.moveCamera(cu); } }
在animation摄像机之前,你可以检查SW和NE的边界是否不太靠近,如果有必要调整边界:
... LatLngBounds bounds = builder.Build(); var sw = bounds.Southwest; var ne = bounds.Northeast; var deltaLat = Math.Abs(sw.Latitude - ne.Latitude); var deltaLon = Math.Abs(sw.Longitude - ne.Longitude); const double zoomN = 0.005; // set whatever zoom coefficient you need!!! if (deltaLat < zoomN) { sw.Latitude = sw.Latitude - (zoomN - deltaLat / 2); ne.Latitude = ne.Latitude + (zoomN - deltaLat / 2); bounds = new LatLngBounds(sw, ne); } else if (deltaLon < zoomN) { sw.Longitude = sw.Longitude - (zoomN - deltaLon / 2); ne.Longitude = ne.Longitude + (zoomN - deltaLon / 2); bounds = new LatLngBounds(sw, ne); } map.animateCamera(CameraUpdateFactory.NewLatLngBounds(bounds, 10);
PS。 我的例子是在C#Xamarin,但你可以轻松地调整它的Java
这是来自您正在使用的include(position)
的API参考 :
“包括build立边界这一点,边界将以最小的方式扩大到包括这一点,更准确地说,它将考虑扩大东西方向的界限(其中一个可能包裹世界)并select两者中较小的一个,如果两个方向都产生一个相同大小的LatLngBounds,就会将其向东扩展。
地图将缩小,直到它可以显示您在for循环中添加的所有标记。
如果您只想缩小到17并仍然显示标记,则首先animation缩放至17级,然后获取边界,然后添加标记。
@Override public void onCameraChange(CameraPosition camPos) { if (camPos.zoom < 17 && mCurrentLoc != null) { // set zoom 17 and disable zoom gestures so map can't be zoomed out // all the way mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,17)); mMap.getUiSettings().setZoomGesturesEnabled(false); } if (camPos.zoom >= 17) { mMap.getUiSettings().setZoomGesturesEnabled(true); } LatLngBounds visibleBounds = mMap.getProjection().getVisibleRegion().latLngBounds; //add the markers
@卡西米尔的方法设定了纬度或经度的最小度数,并且感觉有点难以阅读。 所以我调整它只是在纬度上设置一个最小值,我觉得它更可读:
private LatLngBounds adjustBoundsForMinimumLatitudeDegrees(LatLngBounds bounds, double minLatitudeDegrees) { LatLng sw = bounds.southwest; LatLng ne = bounds.northeast; double visibleLatitudeDegrees = Math.abs(sw.latitude - ne.latitude); if (visibleLatitudeDegrees < minLatitudeDegrees) { LatLng center = bounds.getCenter(); sw = new LatLng(center.latitude - (minLatitudeDegrees / 2), sw.longitude); ne = new LatLng(center.latitude + (minLatitudeDegrees / 2), ne.longitude); bounds = new LatLngBounds(sw, ne); } return bounds; }
林不知道这是否会工作,但你可以试试这个
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
希望能帮助到你
我最终做的是创build我自己的button,并禁用默认的,所以我会完全控制。
像这样的布局放置button:
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="bottom" android:layout_alignParentRight="true" android:layout_alignParentBottom="true"> <Button android:id="@+id/bzoomin" android:layout_width="55dp" android:layout_height="55dp" android:gravity="center" android:textSize="28sp" android:text="+" /> <Button android:id="@+id/bzoomout" android:layout_width="55dp" android:layout_height="55dp" android:gravity="center" android:textSize="23sp" android:text="—" /> </LinearLayout>
然后在代码中禁用默认button并设置新的button:
map.getUiSettings().setZoomControlsEnabled(false); // setup zoom control buttons Button zoomout = (Button) findViewById(R.id.bzoomout); zoomout.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { if(map.getCameraPosition().zoom >= 8.0f){ // Zoom like normal map.animateCamera(CameraUpdateFactory.zoomOut()); }else{ // Do whatever you want if user went too far Messages.toast_short(MapsActivity.this, "Maximum zoom out level reached"); } } }); Button zoomin = (Button) findViewById(R.id.bzoomin); zoomin.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (map.getCameraPosition().zoom <= 14.0f) { // Zoom like normal map.animateCamera(CameraUpdateFactory.zoomIn()); } else { // Do whatever you want if user went too far Messages.toast_short(MapsActivity.this, "Maximum zoom in level reached"); } } });
使用com.google.android.gms:play-services-maps:9.4.0
您可以轻松设置最小/最大缩放。 使用GoogleMap.setMinZoomPreference()
和GoogleMap.setMaxZoomPreference()
您可以设置首选最小和/或最大缩放级别。 更多在这里看到。
我们不能直接限制地图缩放function,但是我们可以尝试像这样获得相同的function。
添加map.setOnCameraChangeListener
final float maxZoom = 10.0f; @Override public void onCameraChange(CameraPosition position) { if (position.zoom > maxZoom) map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom)); }
在新的谷歌地图9.8
com.google.android.gms:play-services-maps:9.8.0
我就是这样工作的
googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { @Override public void onCameraMove() { Log.d(App.TAG, "onCameraMove"); CameraPosition position = googleMap.getCameraPosition(); float maxZoom = 9.0f; if (position.zoom > maxZoom) { googleMap.setMinZoomPreference(maxZoom); } Log.d(App.TAG, "position.zoom = " + position.zoom); } });
map.setMinZoomPreference(floatValue);
您可以通过调用getMaxZoomLevel()
来获得最大缩放级别,然后设置该值:
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(fromPosition, getMaxZoomLevel()));
该地图有一个名为maxZoom的属性。 只需在创build地图时将其设置为您的值