Google Maps API v2:来自CameraPosition的LatLngBounds

有没有一种简单的方法可以通过Android Google Maps API v2从CameraPosition获取可见地图的LatLngBounds ,以便我可以使用OnCameraChangeListener为标记获取新数据。

 mMap.setOnCameraChangeListener(new OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition position) { LatLngBounds bounds = ?; fetchNewData(bounds); } }); 

Solutions Collecting From Web of "Google Maps API v2:来自CameraPosition的LatLngBounds"

自2016年8月起更新

总结现在这个问题的正确答案是使用新的onCameraIdle ,而不是现在已经弃用的OnCameraChangeListener 。 请读下面的内容。

现在,您可以收听“dragEnd”式的活动,甚至可以收听Google Maps for Android最新版本的其他活动。

如文档所示,您可以通过使用新的侦听器来避免OnCameraChangeListener调用多个(又名“ 几个 ”)问题。 例如,您现在可以检查摄像机移动的原因是什么,这是理想的按照要求与fetchData问题耦合。 以下代码大部分是直接从文档中获取的。 还有一点,有必要使用Google Play Services 9.4 。

 public class MyCameraActivity extends FragmentActivity implements OnCameraMoveStartedListener, OnCameraMoveListener, OnCameraMoveCanceledListener, OnCameraIdleListener, OnMapReadyCallback { private GoogleMap mMap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_camera); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap map) { mMap = map; mMap.setOnCameraIdleListener(this); mMap.setOnCameraMoveStartedListener(this); mMap.setOnCameraMoveListener(this); mMap.setOnCameraMoveCanceledListener(this); // Show Sydney on the map. mMap.moveCamera(CameraUpdateFactory .newLatLngZoom(new LatLng(-33.87365, 151.20689), 10)); } @Override public void onCameraMoveStarted(int reason) { if (reason == OnCameraMoveStartedListener.REASON_GESTURE) { Toast.makeText(this, "The user gestured on the map.", Toast.LENGTH_SHORT).show(); } else if (reason == OnCameraMoveStartedListener .REASON_API_ANIMATION) { Toast.makeText(this, "The user tapped something on the map.", Toast.LENGTH_SHORT).show(); } else if (reason == OnCameraMoveStartedListener .REASON_DEVELOPER_ANIMATION) { Toast.makeText(this, "The app moved the camera.", Toast.LENGTH_SHORT).show(); } } @Override public void onCameraMove() { Toast.makeText(this, "The camera is moving.", Toast.LENGTH_SHORT).show(); } @Override public void onCameraMoveCanceled() { Toast.makeText(this, "Camera movement canceled.", Toast.LENGTH_SHORT).show(); } @Override public void onCameraIdle() { Toast.makeText(this, "The camera has stopped moving. Fetch the data from the server!", Toast.LENGTH_SHORT).show(); LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds; fetchData(bounds) } } 

在2016年8月之前解决scheme可提供高效的解决scheme

由于这个问题得到了适当的回答,我想补充一点,可能是下一个问题。

使用OnCameraChangeListener从服务器获取数据时由于触发此方法的频率而出现问题。

有一个问题报告了这个方法在做一个简单的地图滑动时会如何疯狂地频繁触发,因此在这个问题的例子中,即使没有摄像机变化,它也会触发fetchData多个连续的时间进行非常小的摄像机变化,是的,发生相机边界没有改变,但方法被触发。

这可能会影响服务器端的性能,并会通过从服务器连续几十次获取数据而浪费大量设备资源。

你可以在这个链接中find这个问题的解决方法,但是还没有官方的方法来做到这一点,例如,使用合适的dragEnd或者cameraChangeEndcallbackcameraChangeEnd

一个例子,基于从那里的那些,我是如何通过玩的时间间隔打电话和丢弃具有相同边界的电话,以避免上述问题。

 // Keep the current camera bounds private LatLngBounds currentCameraBounds; new GoogleMap.OnCameraChangeListener() { private static int CAMERA_MOVE_REACT_THRESHOLD_MS = 500; private long lastCallMs = Long.MIN_VALUE; @Override public void onCameraChange(CameraPosition cameraPosition) { LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; // Check whether the camera changes report the same boundaries (?!), yes, it happens if (currentCameraBounds.northeast.latitude == bounds.northeast.latitude && currentCameraBounds.northeast.longitude == bounds.northeast.longitude && currentCameraBounds.southwest.latitude == bounds.southwest.latitude && currentCameraBounds.southwest.longitude == bounds.southwest.longitude) { return; } final long snap = System.currentTimeMillis(); if (lastCallMs + CAMERA_MOVE_REACT_THRESHOLD_MS > snap) { lastCallMs = snap; return; } fetchData(bounds); lastCallMs = snap; currentCameraBounds = bounds; } 

您无法从CameraPosition获取LatLngBounds,但您可以通过GoogleMap轻松获取它们。

 private GoogleMap mMap; mMap.setOnCameraChangeListener(new OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition position) { LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds; fetchData(bounds); } });