Mapbox-gl-native: [android] new camera move listeners fire in wrong order

Created on 2 Jun 2017  路  11Comments  路  Source: mapbox/mapbox-gl-native

Platform: Android
Mapbox SDK version: v5.1.0-beta.3

Steps to trigger behavior

Move camera programmatically for ex.:

map.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false, null, true);

Expected behavior

Callbacks are called in order: onCameraMoveStarted() -> onCameraMove() -> onCameraIdle()

Actual behavior

Camera movement finishes with onCameraMoveStarted() or onCameraMove(), or fires infinitely with onCameraMove() callback sometimes mixed up with onCameraMoveCanceled(), or any other combination. It looks really inconsistent.

Android

Most helpful comment

When setting TRACKING_FOLLOW callbacks seemed to be infinite because when we are changing tracking mode to TRACKING_FOLLOW camera is beaing eased to current position and animation duration is being calculated like this animationDuration = (int) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f) but previousUpdateTimeStamp and locationUpdateTimestamp are not being cleared when selecting TRACKING_FOLLOW again, therefore animationDuration is made extremely long which looked like infinite.

All 11 comments

It seems that a OnCameraMoveStarted is called as a result of idle, this seems the source of the misplaced OnCameraMoveCanceled.

the OnCameraMoveStarted call was placed above the following codeblock:

      if (velocityXY < MapboxConstants.VELOCITY_THRESHOLD_IGNORE_FLING) {
        // ignore short flings, these can occur when other gestures just have finished executing
        return false;
      }

While it only should be invoked when the fling isn't ignored.

Related to the OP with ease/animate camera. I'm only seeing expected behaviour:

  • started
  • multiple moves
  • idle

or

  • started
  • multiple moves
  • cancel
  • idle

When camera is in an idle state and I use this code:

map.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(39.489309, -0.360415)), 1000, true, null, true);

I'm getting such callbacks:

08:30:50.897 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - started
08:30:50.948 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:50.989 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.023 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.056 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.090 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.123 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.150 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.190 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.222 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.255 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.289 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.324 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.357 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.377 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.401 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.425 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.453 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.474 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.501 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.525 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.552 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.577 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.609 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.648 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.681 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.714 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.746 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.772 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.798 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.821 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.842 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.867 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.897 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move
08:30:51.925 7746-7746/com.mapbox.mapboxandroiddemo.debug D/Map: camera - move

There is no call to onCameraIdle(). I'm able to reproduce it every time.

Callbacks being finished with onCameraMoveStarted() is resolved by #9192 :)

Thanks for adding the specific easeCamera definition, will try reproducing for #9192.

When setting TRACKING_FOLLOW callbacks seemed to be infinite because when we are changing tracking mode to TRACKING_FOLLOW camera is beaing eased to current position and animation duration is being calculated like this animationDuration = (int) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f) but previousUpdateTimeStamp and locationUpdateTimestamp are not being cleared when selecting TRACKING_FOLLOW again, therefore animationDuration is made extremely long which looked like infinite.

re.

map.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(39.489309, -0.360415)), 1000, true, null, true);

The source of this seems to be providing a null callback. Fixing up code to conform to this.

Both #9194 and #9192 were merged to the release branch. Closing.

i'm having the same issue with SDK 6.6.0-alpha.2 & 6.4.0 & 6.5.0

setting the map OnIdleListener but acts like OnMoveListener
but not indefinite callBcaks

E/MapChangeListenerLogTAG: MoveStarted && int : 3
E/MapChangeListenerLogTAG: Move
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: Move
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle
E/MapChangeListenerLogTAG: MoveStarted && int : 1
E/MapChangeListenerLogTAG: MoveCanceled
E/MapChangeListenerLogTAG: idle

wasn't it resolved ?

what can be done now ?

Hey @Hassan-Fa, I've tested current implementation and I'm unable to reproduce a scenario when canceled isn't followed by idle, which I understand is the issue. Could you provide a reproducible example (I'm aware this might be hard) or do some debugging on your side, especially the logic in the CameraChangeDispatcher?

Was this page helpful?
0 / 5 - 0 ratings