diff options
Diffstat (limited to 'platform')
8 files changed, 89 insertions, 15 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 b49be5c885..8dd05c3f0c 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 @@ -13,6 +13,7 @@ import android.view.animation.LinearInterpolator; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.Projection; import java.util.ArrayList; import java.util.List; @@ -39,12 +40,17 @@ final class LocationAnimatorCoordinator { final List<MapboxAnimator.OnLayerAnimationsValuesChangeListener> layerListeners = new ArrayList<>(); final List<MapboxAnimator.OnCameraAnimationsValuesChangeListener> cameraListeners = new ArrayList<>(); + private final Projection projection; private Location previousLocation; private float previousAccuracyRadius = -1; private float previousCompassBearing = -1; private long locationUpdateTimestamp = -1; private float durationMultiplier; + LocationAnimatorCoordinator(Projection projection) { + this.projection = projection; + } + void addLayerListener(MapboxAnimator.OnLayerAnimationsValuesChangeListener listener) { layerListeners.add(listener); } @@ -81,8 +87,8 @@ final class LocationAnimatorCoordinator { updateLayerAnimators(previousLayerLatLng, targetLatLng, previousLayerBearing, targetLayerBearing); updateCameraAnimators(previousCameraLatLng, previousCameraBearing, targetLatLng, targetCameraBearing); - boolean snap = immediateAnimation(previousCameraLatLng, targetLatLng, currentCameraPosition.zoom) - || immediateAnimation(previousLayerLatLng, targetLatLng, currentCameraPosition.zoom); + boolean snap = immediateAnimation(projection, previousCameraLatLng, targetLatLng) + || immediateAnimation(projection, previousLayerLatLng, targetLatLng); playLocationAnimators(snap ? 0 : getAnimationDuration()); previousLocation = newLocation; @@ -317,7 +323,7 @@ final class LocationAnimatorCoordinator { createNewAnimator(ANIMATOR_CAMERA_LATLNG, new CameraLatLngAnimator(previousCameraTarget, currentTarget, cameraListeners)); - return immediateAnimation(previousCameraTarget, currentTarget, currentCameraPosition.zoom); + return immediateAnimation(projection, previousCameraTarget, currentTarget); } private void resetCameraGpsBearingAnimation(@NonNull CameraPosition currentCameraPosition, boolean isGpsNorth) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java index 1c4cb39578..e426a587d0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationCameraController.java @@ -129,7 +129,7 @@ final class LocationCameraController implements MapboxAnimator.OnCameraAnimation }; CameraPosition currentPosition = mapboxMap.getCameraPosition(); - if (Utils.immediateAnimation(currentPosition.target, target, currentPosition.zoom)) { + if (Utils.immediateAnimation(mapboxMap.getProjection(), currentPosition.target, target)) { mapboxMap.moveCamera( update, callback); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java index b6246f4abc..66eb24acbc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponent.java @@ -1015,7 +1015,7 @@ public final class LocationComponent { locationCameraController = new LocationCameraController( context, mapboxMap, cameraTrackingChangedListener, options, onCameraMoveInvalidateListener); - locationAnimatorCoordinator = new LocationAnimatorCoordinator(); + locationAnimatorCoordinator = new LocationAnimatorCoordinator(mapboxMap.getProjection()); locationAnimatorCoordinator.addLayerListener(locationLayerController); locationAnimatorCoordinator.addCameraListener(locationCameraController); locationAnimatorCoordinator.setTrackingAnimationDurationMultiplier(options 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 29fe413a22..912141c627 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 @@ -24,7 +24,7 @@ final class LocationComponentConstants { 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; + static final double INSTANT_LOCATION_TRANSITION_THRESHOLD = 50_000; // Default interval between location updates static final long DEFAULT_INTERVAL_MILLIS = 1000; 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 7a2415ed5d..2e95da8ad5 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 @@ -16,6 +16,7 @@ import android.support.v4.content.ContextCompat; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.Projection; import static com.mapbox.mapboxsdk.location.LocationComponentConstants.INSTANT_LOCATION_TRANSITION_THRESHOLD; @@ -92,13 +93,10 @@ public final class Utils { return (float) (location.getAccuracy() * (1 / metersPerPixel)); } - static boolean immediateAnimation(LatLng current, @NonNull LatLng target, double zoom) { - // TODO: calculate the value based on the projection + static boolean immediateAnimation(@NonNull Projection projection, @NonNull LatLng current, @NonNull LatLng target) { + double metersPerPixel = projection.getMetersPerPixelAtLatitude((current.getLatitude() + target.getLatitude()) / 2); double distance = current.distanceTo(target); - if (zoom > 10) { - distance *= zoom; - } - return distance > INSTANT_LOCATION_TRANSITION_THRESHOLD; + return distance / metersPerPixel > INSTANT_LOCATION_TRANSITION_THRESHOLD; } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinatorTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinatorTest.kt index 2c94642610..fad71237ab 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinatorTest.kt +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationAnimatorCoordinatorTest.kt @@ -6,12 +6,14 @@ import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_TRACKING_TILT_ANIM_DURATION import com.mapbox.mapboxsdk.location.LocationComponentConstants.DEFAULT_TRACKING_ZOOM_ANIM_DURATION import com.mapbox.mapboxsdk.location.MapboxAnimator.* +import com.mapbox.mapboxsdk.maps.Projection import junit.framework.Assert.assertEquals import junit.framework.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito +import org.mockito.Mockito.mock import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) @@ -22,7 +24,7 @@ class LocationAnimatorCoordinatorTest { @Before fun setUp() { - locationAnimatorCoordinator = LocationAnimatorCoordinator() + locationAnimatorCoordinator = LocationAnimatorCoordinator(mock(Projection::class.java)) } @Test diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java index 4f950cebac..475426f77c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/location/LocationCameraControllerTest.java @@ -454,6 +454,9 @@ public class LocationCameraControllerTest { public void transition_trackingChanged() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -478,6 +481,9 @@ public class LocationCameraControllerTest { public void transition_trackingNotChanged() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -504,6 +510,9 @@ public class LocationCameraControllerTest { public void transition_canceled() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -528,6 +537,9 @@ public class LocationCameraControllerTest { public void transition_mapboxCallbackFinished() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -558,9 +570,47 @@ public class LocationCameraControllerTest { } @Test + public void transition_mapboxCallbackFinishedImmediately() { + MapboxMap mapboxMap = mock(MapboxMap.class); + when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1)); + LocationCameraController camera = buildCamera(mapboxMap); + camera.initializeOptions(mock(LocationComponentOptions.class)); + final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); + Location location = mock(Location.class); + when(location.getLatitude()).thenReturn(1.0); + when(location.getLongitude()).thenReturn(1.0); + when(location.getBearing()).thenReturn(30f); + when(location.getAltitude()).thenReturn(0.0); + + ArgumentCaptor<MapboxMap.CancelableCallback> callbackCaptor + = ArgumentCaptor.forClass(MapboxMap.CancelableCallback.class); + + camera.setCameraMode(CameraMode.TRACKING, location, listener); + + CameraPosition.Builder builder = new CameraPosition.Builder().target(new LatLng(location)); + verify(mapboxMap).moveCamera( + eq(CameraUpdateFactory.newCameraPosition(builder.build())), + callbackCaptor.capture()); + + Assert.assertTrue(camera.isTransitioning()); + + callbackCaptor.getValue().onFinish(); + + Assert.assertFalse(camera.isTransitioning()); + + verify(listener).onLocationCameraTransitionFinished(CameraMode.TRACKING); + } + + @Test public void transition_mapboxCallbackCanceled() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -594,6 +644,9 @@ public class LocationCameraControllerTest { public void transition_mapboxAnimateBearing() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -616,6 +669,9 @@ public class LocationCameraControllerTest { public void transition_mapboxAnimateNorth() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -638,6 +694,9 @@ public class LocationCameraControllerTest { public void transition_animatorValuesDuringTransition() { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getCameraPosition()).thenReturn(CameraPosition.DEFAULT); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); LocationCameraController camera = buildCamera(mapboxMap); camera.initializeOptions(mock(LocationComponentOptions.class)); final OnLocationCameraTransitionListener listener = mock(OnLocationCameraTransitionListener.class); @@ -674,6 +733,9 @@ public class LocationCameraControllerTest { private LocationCameraController buildCamera(OnCameraTrackingChangedListener onCameraTrackingChangedListener) { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getUiSettings()).thenReturn(mock(UiSettings.class)); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); MoveGestureDetector moveGestureDetector = mock(MoveGestureDetector.class); OnCameraMoveInvalidateListener onCameraMoveInvalidateListener = mock(OnCameraMoveInvalidateListener.class); AndroidGesturesManager initialGesturesManager = mock(AndroidGesturesManager.class); @@ -685,6 +747,9 @@ public class LocationCameraControllerTest { private LocationCameraController buildCamera(MoveGestureDetector moveGestureDetector) { MapboxMap mapboxMap = mock(MapboxMap.class); when(mapboxMap.getUiSettings()).thenReturn(mock(UiSettings.class)); + Projection projection = mock(Projection.class); + when(mapboxMap.getProjection()).thenReturn(projection); + when(projection.getMetersPerPixelAtLatitude(any(Double.class))).thenReturn(Double.valueOf(1000)); OnCameraTrackingChangedListener onCameraTrackingChangedListener = mock(OnCameraTrackingChangedListener.class); OnCameraMoveInvalidateListener onCameraMoveInvalidateListener = mock(OnCameraMoveInvalidateListener.class); AndroidGesturesManager initialGesturesManager = mock(AndroidGesturesManager.class); 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 94e1f079f3..4c7baad939 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 @@ -1165,12 +1165,15 @@ class LocationComponentTest : BaseActivityTest() { uiController: UiController, context: Context) { component.activateLocationComponent(context, mapboxMap.style!!, 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) + + val target = LatLng(51.0, 17.0) mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(target)) + mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(15.0)) mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(90.0)) + assertTrue(Utils.immediateAnimation(mapboxMap.projection, mapboxMap.cameraPosition.target, LatLng(location))) + component.cameraMode = CameraMode.TRACKING_GPS assertEquals(location.bearing.toDouble(), mapboxMap.cameraPosition.bearing, 0.1) assertEquals(location.latitude, mapboxMap.cameraPosition.target.latitude, 0.1) |