我目前正致力于使用Google地图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);
此代码工作正常但我想在缩放级别达到17.0f时停止动画; 看来map API没有这样的方法来控制缩放级别。 有人知道解决这个问题的任何想法吗?
答案 0 :(得分:25)
我在Google Maps API中找不到任何直接解决方案。这个问题的一个潜在解决方案是收听OnCameraChange event:每当此事件触发且缩放级别高于最大缩放级别时,就可以调用animateCamera()。结果代码如下:
@Override
public void onCameraChange(CameraPosition position) {
float maxZoom = 17.0f;
if (position.zoom > maxZoom)
map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
答案 1 :(得分:25)
Google Maps API的最新update介绍了您需要的功能:
GoogleMap.setMaxZoomPreference()
GoogleMap.setMinZoomPreference()
但它仍然无法阻止动画播放。
答案 2 :(得分:13)
以下是Arvis解决方案的相应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;
}
答案 3 :(得分:12)
来自Android doc: 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);
答案 4 :(得分:7)
与Arvis解决方案相同,但使用Location
的[distanceBetween()
](http://developer.android.com/reference/android/location/Location.html#distanceBetween(double,double,double,double,float []))方法来计算点到点之间的距离: / p>
@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);
}
}
答案 5 :(得分:3)
在为相机设置动画之前,您可以检查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。我的例子是用于Xamarin的c#,但你可以很容易地调整它为java
答案 6 :(得分:2)
这来自您使用的include(position)
的{{3}}:
“包括构建边界的这一点。边界将以最小的方式扩展以包含这一点。 更确切地说,它将考虑在东向和向西方向上扩展边界(其中一个可以环绕世界)并选择两者中较小的一个。如果两个方向都产生相同大小的LatLngBounds,则会向东方向延伸。“
地图将缩小,直到它可以显示您在for循环中添加的所有标记。
如果您只想缩小到17并仍然显示标记,请先设置缩放级别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
答案 7 :(得分:1)
@ kasimir的方法设定纬度或经度的最小度数,感觉有点难以阅读。所以我把它调整到只设置纬度的最小值,我觉得它更具可读性:
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;
}
答案 8 :(得分:0)
我最终做的是创建我自己的按钮并禁用默认按钮,这样我就可以完全控制。
在布局中放置按钮的东西是这样的:
<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>
然后在代码中禁用默认按钮并设置我们的新按钮:
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");
}
}
});
答案 9 :(得分:0)
缩放级别如下:
<块引用>1f: World
5f: Landmass/continent
10f: City
15f: Streets
20f: Buildings
val setMin = 10f
val setMax = 20f
googleMap.setMaxZoomPreference(setMax)
googleMap.setMinZoomPreference(setMin)
答案 10 :(得分:0)
map.setMinZoomPreference(floatValue);
答案 11 :(得分:0)
在新的Google地图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);
}
});
答案 12 :(得分:0)
我们不能直接限制地图zoomin功能,但我们可以尝试获得这样的相同功能。
添加map.setOnCameraChangeListener
final float maxZoom = 10.0f;
@Override
public void onCameraChange(CameraPosition position) {
if (position.zoom > maxZoom)
map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
答案 13 :(得分:0)
使用 protected void BindEvents(WebControl ctrl, string methodName, string eventType)
{
System.Reflection.EventInfo eventInfo = ctrl.GetType().GetEvent(eventType);
var delegateType = eventInfo.EventHandlerType.GetMethod("Invoke");
var methodInfo = this.GetType().GetMethod(methodName);
var parameters = delegateType.GetParameters();
if (parameters.Length!=2)
throw new NotImplementedException(); // Can make switch and multiple CreateAction methods to handle
var genericCreateAction = this.GetType().GetMethod("CreateAction2");
var parameterTypes = parameters.Select(o => o.ParameterType).ToArray<Type>();
var createAction = genericCreateAction.MakeGenericMethod(parameterTypes);
var action = (Delegate)createAction.Invoke(this, new object[] { methodInfo, eventType });
var properTypeAction = Delegate.CreateDelegate(eventInfo.EventHandlerType, action.Target, action.Method);
eventInfo.AddEventHandler(ctrl, properTypeAction);
}
public Action<T1, T2> CreateAction2<T1, T2>(MethodInfo methodInfo, string eventName)
{
return (Action<T1, T2>)((p1, p2) => { methodInfo.Invoke(this, new object[] { p1, p2, eventName }); });
}
,您可以轻松设置最小/最大缩放。使用com.google.android.gms:play-services-maps:9.4.0
和GoogleMap.setMinZoomPreference()
,您可以设置首选的最小和/或最大缩放级别。更多信息,请参阅here。
答案 14 :(得分:0)
我不确定这是否有效,但你可以试试吗
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
希望有所帮助
答案 15 :(得分:-2)
您可以通过调用getMaxZoomLevel()
获取最大缩放级别,然后设置该值:
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(fromPosition, getMaxZoomLevel()));
答案 16 :(得分:-3)
地图有一个名为maxZoom的属性。只需在创建地图时将其设置为您的值