来自CameraPosition的Google Maps API v2:LatLngBounds

Gar*_*con 40 android google-maps android-maps

是否有一种简单的方法LatLngBounds可以从CameraPositionAndroid Google Maps API v2中获取可见地图,以便我可以使用它OnCameraChangeListener来获取标记的新数据.

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

Gar*_*con 77

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

private GoogleMap mMap;

mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition position) {
                LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds;
                fetchData(bounds);
            }
        });
Run Code Online (Sandbox Code Playgroud)

  • @capdragon等等,什么?地图投影正是定义可见区域的4个坐标的定义 (4认同)
  • 在这种情况下,"投影"涉及世界到屏幕投影(而不是地图投影),并且将考虑相机旋转和倾斜. (3认同)

Edu*_*rdo 36

自2016年8月起更新

总结现在针对此问题的正确答案是使用new onCameraIdle,而不是OnCameraChangeListener现在已弃用的.请仔细阅读如何.

现在,您可以在最新版本的Google Maps for Android上收听类似"dragEnd"的活动,甚至是其他活动.

文档中所示,您可以通过使用新的侦听器来避免多个(也称为" 几个 ")调用的问题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)
    }
}
Run Code Online (Sandbox Code Playgroud)

在2016年8月之前解决有效解决方案

由于问题得到了适当的回答,我想在下一个问题上补充一点.

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

有一个问题是关于在进行简单的地图滑动时如何经常触发这种方法的问题,因此在问题的例子中,它会触发fetchData多次连续时间以进行非常少的相机更改,即使没有相机更改,是的,它会发生相机边界没有改变,但方法被触发.

这可能会影响服务器端性能,并且会通过从服务器顺序提取数十次来浪费大量设备资源.

您可以在该链接中找到此问题的变通方法,但还没有正式的方法来执行此操作,例如,使用期望的dragEndcameraChangeEnd回调.

下面的一个例子,基于那些,我是如何通过播放呼叫的时间间隔和丢弃具有相同边界的呼叫来避免上述问题.

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

}
Run Code Online (Sandbox Code Playgroud)