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

Commit

Permalink
[android] - move camera and puck immediately when starting to track a…
Browse files Browse the repository at this point in the history
…nd displacement is big
  • Loading branch information
LukasPaczos committed Oct 3, 2018
1 parent b31245b commit 5bfdd9f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
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

0 comments on commit 5bfdd9f

Please sign in to comment.