From a364270af62d7f373f35611cefbcbe507d4df621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 9 May 2019 19:11:10 +0200 Subject: [android] normalize previous rotation values of the location animator --- .../location/LocationAnimatorCoordinator.java | 3 + .../java/com/mapbox/mapboxsdk/location/Utils.java | 10 ++ .../location/LocationAnimatorCoordinatorTest.kt | 102 +++++++++++++++++++++ 3 files changed, 115 insertions(+) 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 35e5efc266..50bbb7acfc 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 @@ -196,6 +196,9 @@ final class LocationAnimatorCoordinator { float previousBearing, float targetBearing) { createNewLatLngAnimator(ANIMATOR_LAYER_LATLNG, previousLatLng, targetLatLng); + // Because Location bearing values are normalized to [0, 360] + // we need to do the same for the previous bearing value to determine the shortest path + previousBearing = Utils.normalize(previousBearing); float normalizedLayerBearing = Utils.shortestRotation(targetBearing, previousBearing); createNewFloatAnimator(ANIMATOR_LAYER_GPS_BEARING, previousBearing, normalizedLayerBearing); } 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 49f9a7c43c..b352dc9190 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 @@ -36,6 +36,16 @@ public final class Utils { return heading; } + /** + * Normalizes an angle to be in the [0, 360] range. + * + * @param angle the provided angle + * @return the normalized angle + */ + public static float normalize(float angle) { + return (angle % 360 + 360) % 360; + } + static Bitmap generateShadow(Drawable drawable, float elevation) { int width = drawable.getIntrinsicWidth(); int height = drawable.getIntrinsicHeight(); 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 c654e405b6..1bc92ed7e3 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 @@ -118,6 +118,108 @@ class LocationAnimatorCoordinatorTest { assertEquals(location.bearing, layerBearingTarget) } + @Test + fun feedNewLocation_animatorValue_correctRotation_1() { + val location = Location("") + location.latitude = 51.0 + location.longitude = 17.0 + location.bearing = 0f + + val animator = mockk(relaxed = true) + every { animator.animatedValue } returns 270f + locationAnimatorCoordinator.animatorArray.put(ANIMATOR_LAYER_GPS_BEARING, animator) + + locationAnimatorCoordinator.feedNewLocation(location, cameraPosition, false) + + val layerBearingTarget = locationAnimatorCoordinator.animatorArray[ANIMATOR_LAYER_GPS_BEARING]?.target as Float + assertEquals(360f, layerBearingTarget) + } + + @Test + fun feedNewLocation_animatorValue_correctRotation_2() { + val location = Location("") + location.latitude = 51.0 + location.longitude = 17.0 + location.bearing = 90f + + val animator = mockk(relaxed = true) + every { animator.animatedValue } returns 280f + locationAnimatorCoordinator.animatorArray.put(ANIMATOR_LAYER_GPS_BEARING, animator) + + locationAnimatorCoordinator.feedNewLocation(location, cameraPosition, false) + + val layerBearingTarget = locationAnimatorCoordinator.animatorArray[ANIMATOR_LAYER_GPS_BEARING]?.target as Float + assertEquals(450f, layerBearingTarget) + } + + @Test + fun feedNewLocation_animatorValue_correctRotation_3() { + val location = Location("") + location.latitude = 51.0 + location.longitude = 17.0 + location.bearing = 300f + + val animator = mockk(relaxed = true) + every { animator.animatedValue } returns 450f + locationAnimatorCoordinator.animatorArray.put(ANIMATOR_LAYER_GPS_BEARING, animator) + + locationAnimatorCoordinator.feedNewLocation(location, cameraPosition, false) + + val layerBearingTarget = locationAnimatorCoordinator.animatorArray[ANIMATOR_LAYER_GPS_BEARING]?.target as Float + assertEquals(-60f, layerBearingTarget) + } + + @Test + fun feedNewLocation_animatorValue_correctRotation_4() { + val location = Location("") + location.latitude = 51.0 + location.longitude = 17.0 + location.bearing = 350f + + val animator = mockk(relaxed = true) + every { animator.animatedValue } returns 10f + locationAnimatorCoordinator.animatorArray.put(ANIMATOR_LAYER_GPS_BEARING, animator) + + locationAnimatorCoordinator.feedNewLocation(location, cameraPosition, false) + + val layerBearingTarget = locationAnimatorCoordinator.animatorArray[ANIMATOR_LAYER_GPS_BEARING]?.target as Float + assertEquals(-10f, layerBearingTarget) + } + + @Test + fun feedNewLocation_animatorValue_correctRotation_5() { + val location = Location("") + location.latitude = 51.0 + location.longitude = 17.0 + location.bearing = 90f + + val animator = mockk(relaxed = true) + every { animator.animatedValue } returns -280f + locationAnimatorCoordinator.animatorArray.put(ANIMATOR_LAYER_GPS_BEARING, animator) + + locationAnimatorCoordinator.feedNewLocation(location, cameraPosition, false) + + val layerBearingTarget = locationAnimatorCoordinator.animatorArray[ANIMATOR_LAYER_GPS_BEARING]?.target as Float + assertEquals(90f, layerBearingTarget) + } + + @Test + fun feedNewLocation_animatorValue_correctRotation_6() { + val location = Location("") + location.latitude = 51.0 + location.longitude = 17.0 + location.bearing = 270f + + val animator = mockk(relaxed = true) + every { animator.animatedValue } returns -350f + locationAnimatorCoordinator.animatorArray.put(ANIMATOR_LAYER_GPS_BEARING, animator) + + locationAnimatorCoordinator.feedNewLocation(location, cameraPosition, false) + + val layerBearingTarget = locationAnimatorCoordinator.animatorArray[ANIMATOR_LAYER_GPS_BEARING]?.target as Float + assertEquals(-90f, layerBearingTarget) + } + @Test fun feedNewLocation_isNorth_animatorsAreCreated() { val location = Location("") -- cgit v1.2.1