Skip to content

Commit 578bd04

Browse files
author
Łukasz Paczos
committed
[LLP] move camera and puck immediately when starting to track and displacement is big
1 parent 95d5fe6 commit 578bd04

5 files changed

Lines changed: 52 additions & 11 deletions

File tree

app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,30 @@ class LocationLayerPluginTest {
10631063
executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity))
10641064
}
10651065

1066+
@Test
1067+
fun cameraPositionSnappedToTargetIfExceedsThreshold() {
1068+
val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
1069+
override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
1070+
uiController: UiController, context: Context) {
1071+
val target = LatLng(51.0, 17.0)
1072+
assertTrue(target.distanceTo(LatLng(location)) > LocationLayerConstants.INSTANT_LOCATION_TRANSITION_THRESHOLD)
1073+
1074+
plugin.cameraMode = CameraMode.NONE
1075+
plugin.forceLocationUpdate(location)
1076+
plugin.isLocationLayerEnabled = true
1077+
mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(target))
1078+
mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0))
1079+
plugin.cameraMode = CameraMode.TRACKING_GPS
1080+
1081+
assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1)
1082+
assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1)
1083+
assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1)
1084+
}
1085+
}
1086+
1087+
executePluginTest(pluginAction, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity))
1088+
}
1089+
10661090
@Test
10671091
fun onPluginInitialized_defaultCompassEngineIsProvided() {
10681092
val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {

plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ final class LocationLayerConstants {
2525
// Default animation duration for tilting while tracking.
2626
static final long DEFAULT_TRACKING_TILT_ANIMATION_DURATION = 1250;
2727

28+
// Threshold value to perform immediate camera/layer position update.
29+
static final double INSTANT_LOCATION_TRANSITION_THRESHOLD = 500_000;
30+
2831
// Sources
2932
static final String LOCATION_SOURCE = "mapbox-location-source";
3033
static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing";

plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,8 @@ public boolean isLocationLayerEnabled() {
269269
*/
270270
public void setCameraMode(@CameraMode.Mode int cameraMode) {
271271
boolean isGpsNorth = cameraMode == CameraMode.TRACKING_GPS_NORTH;
272-
pluginAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth);
273272
locationLayerCamera.setCameraMode(cameraMode);
273+
pluginAnimatorCoordinator.resetAllCameraAnimations(mapboxMap.getCameraPosition(), isGpsNorth);
274274
}
275275

276276
/**

plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/PluginAnimatorCoordinator.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.os.SystemClock;
88
import android.support.annotation.NonNull;
99
import android.support.annotation.Nullable;
10+
import android.support.v4.view.animation.FastOutSlowInInterpolator;
1011
import android.view.animation.LinearInterpolator;
1112

1213
import com.mapbox.mapboxsdk.camera.CameraPosition;
@@ -21,6 +22,7 @@
2122
import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_RADIUS_ANIMATION_DURATION;
2223
import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.COMPASS_UPDATE_RATE_MS;
2324
import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.MAX_ANIMATION_DURATION_MS;
25+
import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.INSTANT_LOCATION_TRANSITION_THRESHOLD;
2426
import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.TRANSITION_ANIMATION_DURATION_MS;
2527
import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_COMPASS_BEARING;
2628
import static com.mapbox.mapboxsdk.plugins.locationlayer.PluginAnimator.ANIMATOR_CAMERA_GPS_BEARING;
@@ -82,7 +84,9 @@ void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition curr
8284
updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing);
8385
updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing);
8486

85-
playLocationAnimators(getAnimationDuration());
87+
boolean snap = immediateAnimation(previousCameraLatLng, targetLatLng, currentCameraPosition.zoom)
88+
|| immediateAnimation(previousLayerLatLng, targetLatLng, currentCameraPosition.zoom);
89+
playLocationAnimators(snap ? 0 : getAnimationDuration());
8690

8791
previousLocation = newLocation;
8892
}
@@ -289,32 +293,34 @@ private void playCameraLocationAnimators(long duration) {
289293
locationAnimators.add(animatorMap.get(ANIMATOR_CAMERA_GPS_BEARING));
290294
AnimatorSet locationAnimatorSet = new AnimatorSet();
291295
locationAnimatorSet.playTogether(locationAnimators);
292-
locationAnimatorSet.setInterpolator(new LinearInterpolator());
296+
locationAnimatorSet.setInterpolator(new FastOutSlowInInterpolator());
293297
locationAnimatorSet.setDuration(duration);
294298
locationAnimatorSet.start();
295299
}
296300

297301
void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) {
298302
resetCameraCompassAnimation(currentCameraPosition);
299-
resetCameraLocationAnimations(currentCameraPosition, isGpsNorth);
300-
playCameraLocationAnimators(TRANSITION_ANIMATION_DURATION_MS);
303+
boolean snap = resetCameraLocationAnimations(currentCameraPosition, isGpsNorth);
304+
playCameraLocationAnimators(snap ? 0 : TRANSITION_ANIMATION_DURATION_MS);
301305
}
302306

303-
private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) {
304-
resetCameraLatLngAnimation(currentCameraPosition);
307+
private boolean resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) {
305308
resetCameraGpsBearingAnimation(currentCameraPosition, isGpsNorth);
309+
return resetCameraLatLngAnimation(currentCameraPosition);
306310
}
307311

308-
private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) {
312+
private boolean resetCameraLatLngAnimation(CameraPosition currentCameraPosition) {
309313
CameraLatLngAnimator animator = (CameraLatLngAnimator) animatorMap.get(ANIMATOR_CAMERA_LATLNG);
310314
if (animator == null) {
311-
return;
315+
return false;
312316
}
313317

314318
LatLng currentTarget = animator.getTarget();
315319
LatLng previousCameraTarget = currentCameraPosition.target;
316320
createNewAnimator(ANIMATOR_CAMERA_LATLNG,
317321
new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners));
322+
323+
return immediateAnimation(previousCameraTarget, currentTarget, currentCameraPosition.zoom);
318324
}
319325

320326
private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) {
@@ -377,4 +383,13 @@ private void cancelAnimator(@PluginAnimator.Type int animatorType) {
377383
void setTrackingAnimationDurationMultiplier(float trackingAnimationDurationMultiplier) {
378384
this.durationMultiplier = trackingAnimationDurationMultiplier;
379385
}
386+
387+
private boolean immediateAnimation(LatLng current, LatLng target, double zoom) {
388+
// TODO: 02/10/2018 calculate the value based on the projection
389+
double distance = current.distanceTo(target);
390+
if (zoom > 10) {
391+
distance *= zoom;
392+
}
393+
return distance > INSTANT_LOCATION_TRANSITION_THRESHOLD;
394+
}
380395
}

plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ static float calculateZoomLevelRadius(@NonNull MapboxMap mapboxMap, @Nullable Lo
8585
if (location == null) {
8686
return 0;
8787
}
88-
double metersPerPixel = mapboxMap.getProjection().getMetersPerPixelAtLatitude(
89-
location.getLatitude());
88+
double metersPerPixel = mapboxMap.getProjection().getMetersPerPixelAtLatitude(location.getLatitude());
9089
return (float) (location.getAccuracy() * (1 / metersPerPixel));
9190
}
9291

0 commit comments

Comments
 (0)