From 7de2f4f4e160977743532b3d419332b9149587e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 3 Oct 2018 11:30:54 +0200 Subject: [android] - move camera and puck immediately when starting to track and displacement is big --- .../location/LocationAnimatorCoordinator.java | 31 ++++++++++++++++------ .../location/LocationComponentConstants.java | 3 +++ .../java/com/mapbox/mapboxsdk/location/Utils.java | 3 +-- .../mapboxsdk/location/LocationComponentTest.kt | 23 ++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java index 789adbbaea..0a6c9b5ddc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinator.java @@ -6,6 +6,7 @@ import android.location.Location; import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.util.SparseArray; import android.view.animation.LinearInterpolator; @@ -18,6 +19,7 @@ import java.util.List; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.ACCURACY_RADIUS_ANIMATION_DURATION; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.COMPASS_UPDATE_RATE_MS; +import static com.mapbox.mapboxsdk.location.LocationComponentConstants.INSTANT_LOCATION_TRANSITION_THRESHOLD; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.MAX_ANIMATION_DURATION_MS; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.TRANSITION_ANIMATION_DURATION_MS; import static com.mapbox.mapboxsdk.location.MapboxAnimator.ANIMATOR_CAMERA_COMPASS_BEARING; @@ -79,7 +81,9 @@ final class LocationAnimatorCoordinator { updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing); updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing); - playLocationAnimators(getAnimationDuration()); + boolean snap = immediateAnimation(previousCameraLatLng, targetLatLng, currentCameraPosition.zoom) + || immediateAnimation(previousLayerLatLng, targetLatLng, currentCameraPosition.zoom); + playLocationAnimators(snap ? 0 : getAnimationDuration()); previousLocation = newLocation; } @@ -286,32 +290,34 @@ final class LocationAnimatorCoordinator { locationAnimators.add(animatorArray.get(ANIMATOR_CAMERA_GPS_BEARING)); AnimatorSet locationAnimatorSet = new AnimatorSet(); locationAnimatorSet.playTogether(locationAnimators); - locationAnimatorSet.setInterpolator(new LinearInterpolator()); + locationAnimatorSet.setInterpolator(new FastOutSlowInInterpolator()); locationAnimatorSet.setDuration(duration); locationAnimatorSet.start(); } void resetAllCameraAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { resetCameraCompassAnimation(currentCameraPosition); - resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); - playCameraLocationAnimators(TRANSITION_ANIMATION_DURATION_MS); + boolean snap = resetCameraLocationAnimations(currentCameraPosition, isGpsNorth); + playCameraLocationAnimators(snap ? 0 : TRANSITION_ANIMATION_DURATION_MS); } - private void resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { - resetCameraLatLngAnimation(currentCameraPosition); + private boolean resetCameraLocationAnimations(CameraPosition currentCameraPosition, boolean isGpsNorth) { resetCameraGpsBearingAnimation(currentCameraPosition, isGpsNorth); + return resetCameraLatLngAnimation(currentCameraPosition); } - private void resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { + private boolean resetCameraLatLngAnimation(CameraPosition currentCameraPosition) { CameraLatLngAnimator animator = (CameraLatLngAnimator) animatorArray.get(ANIMATOR_CAMERA_LATLNG); if (animator == null) { - return; + return false; } LatLng currentTarget = animator.getTarget(); LatLng previousCameraTarget = currentCameraPosition.target; createNewAnimator(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners)); + + return immediateAnimation(previousCameraTarget, currentTarget, currentCameraPosition.zoom); } private void resetCameraGpsBearingAnimation(CameraPosition currentCameraPosition, boolean isGpsNorth) { @@ -375,4 +381,13 @@ final class LocationAnimatorCoordinator { void setTrackingAnimationDurationMultiplier(float trackingAnimationDurationMultiplier) { this.durationMultiplier = trackingAnimationDurationMultiplier; } + + private boolean immediateAnimation(LatLng current, LatLng target, double zoom) { + // TODO: calculate the value based on the projection + double distance = current.distanceTo(target); + if (zoom > 10) { + distance *= zoom; + } + return distance > INSTANT_LOCATION_TRANSITION_THRESHOLD; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java index 40aae5bb6f..4376ef4e60 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentConstants.java @@ -23,6 +23,9 @@ final class LocationComponentConstants { // Default animation duration for tilting while tracking. static final long DEFAULT_TRACKING_TILT_ANIM_DURATION = 1250; + // Threshold value to perform immediate camera/layer position update. + static final double INSTANT_LOCATION_TRANSITION_THRESHOLD = 500_000; + // Sources static final String LOCATION_SOURCE = "mapbox-location-source"; static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing"; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/Utils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/Utils.java index ff0a9ce193..553678709e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/Utils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/Utils.java @@ -84,8 +84,7 @@ public final class Utils { if (location == null) { return 0; } - double metersPerPixel = mapboxMap.getProjection().getMetersPerPixelAtLatitude( - location.getLatitude()); + double metersPerPixel = mapboxMap.getProjection().getMetersPerPixelAtLatitude(location.getLatitude()); return (float) (location.getAccuracy() * (1 / metersPerPixel)); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt index aa3e2eea6f..444b478219 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/location/LocationComponentTest.kt @@ -1099,6 +1099,29 @@ class LocationComponentTest : BaseActivityTest() { executeComponentTest(componentAction) } + @Test + fun cameraPositionSnappedToTargetIfExceedsThreshold() { + val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { + override fun onLocationComponentAction(component: LocationComponent, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + component.activateLocationComponent(context, false) + component.isLocationComponentEnabled = true + val target = LatLng(51.0, 17.0) + assertTrue(target.distanceTo(LatLng(location)) > LocationComponentConstants.INSTANT_LOCATION_TRANSITION_THRESHOLD) + component.cameraMode = CameraMode.NONE + component.forceLocationUpdate(location) + mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(target)) + mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) + component.cameraMode = CameraMode.TRACKING_GPS + assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) + assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) + assertEquals(location.longitude, mapboxMap.cameraPosition.target.longitude, 0.1) + } + } + + executeComponentTest(componentAction) + } + @Test fun compassEngine_onComponentInitializedDefaultIsProvided() { val componentAction = object : LocationComponentAction.OnPerformLocationComponentAction { -- cgit v1.2.1