Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Move camera and puck immediately when starting to track and displacement is big #13013

Merged
merged 1 commit into from Oct 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -6,6 +6,7 @@
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;

Expand All @@ -18,6 +19,7 @@

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;
Expand Down Expand Up @@ -79,7 +81,9 @@ void feedNewLocation(@NonNull Location newLocation, @NonNull CameraPosition curr
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;
}
Expand Down Expand Up @@ -286,32 +290,34 @@ private void playCameraLocationAnimators(long duration) {
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) {
Expand Down Expand Up @@ -375,4 +381,13 @@ private void cancelAnimator(@MapboxAnimator.Type int animatorType) {
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;
}
}
Expand Up @@ -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";
Expand Down
Expand Up @@ -84,8 +84,7 @@ static float calculateZoomLevelRadius(@NonNull MapboxMap mapboxMap, @Nullable Lo
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));
}

Expand Down
Expand Up @@ -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 {
Expand Down