summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java11
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java46
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt14
4 files changed, 68 insertions, 18 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
index d2694b5b8a..6156b3af73 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
@@ -87,6 +87,11 @@ public class MapboxConstants {
public static final double MAX_ABSOLUTE_SCALE_VELOCITY_CHANGE = 2.5;
/**
+ * Maximum possible zoom change during the quick zoom gesture executed across the whole screen
+ */
+ public static final double QUICK_ZOOM_MAX_ZOOM_CHANGE = 4.0;
+
+ /**
* Scale velocity animation duration multiplier.
*/
public static final double SCALE_VELOCITY_ANIMATION_DURATION_MULTIPLIER = 150;
@@ -156,12 +161,18 @@ public class MapboxConstants {
/**
* The currently used minimum scale factor to clamp to when a quick zoom gesture occurs
+ *
+ * @deprecated unused
*/
+ @Deprecated
public static final float MINIMUM_SCALE_FACTOR_CLAMP = 0.00f;
/**
* The currently used maximum scale factor to clamp to when a quick zoom gesture occurs
+ *
+ * @deprecated unused
*/
+ @Deprecated
public static final float MAXIMUM_SCALE_FACTOR_CLAMP = 0.15f;
/**
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
index 0b28c669af..90e3934f7c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
@@ -4,6 +4,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.PointF;
import android.os.Handler;
import android.support.annotation.NonNull;
@@ -31,11 +32,13 @@ import java.util.concurrent.CopyOnWriteArrayList;
import static com.mapbox.mapboxsdk.constants.MapboxConstants.MAXIMUM_ANGULAR_VELOCITY;
import static com.mapbox.mapboxsdk.constants.MapboxConstants.MAX_ABSOLUTE_SCALE_VELOCITY_CHANGE;
+import static com.mapbox.mapboxsdk.constants.MapboxConstants.QUICK_ZOOM_MAX_ZOOM_CHANGE;
import static com.mapbox.mapboxsdk.constants.MapboxConstants.ROTATE_VELOCITY_RATIO_THRESHOLD;
import static com.mapbox.mapboxsdk.constants.MapboxConstants.SCALE_VELOCITY_ANIMATION_DURATION_MULTIPLIER;
import static com.mapbox.mapboxsdk.constants.MapboxConstants.SCALE_VELOCITY_RATIO_THRESHOLD;
import static com.mapbox.mapboxsdk.constants.MapboxConstants.ZOOM_RATE;
import static com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener.REASON_API_GESTURE;
+import static com.mapbox.mapboxsdk.utils.MathUtils.normalize;
/**
* Manages gestures events on a MapView.
@@ -76,6 +79,9 @@ final class MapGestureDetector {
@Nullable
private PointF constantFocalPoint;
+ @NonNull
+ private PointF doubleTapFocalPoint = new PointF();
+
private AndroidGesturesManager gesturesManager;
private Animator scaleAnimator;
@@ -321,8 +327,6 @@ final class MapGestureDetector {
}
private final class StandardGestureListener extends StandardGestureDetector.SimpleStandardOnGestureListener {
-
- private PointF doubleTapFocalPoint;
private final float doubleTapMovementThreshold;
StandardGestureListener(float doubleTapMovementThreshold) {
@@ -495,6 +499,8 @@ final class MapGestureDetector {
private final double scaleVelocityRatioThreshold;
private boolean quickZoom;
private float spanSinceLast;
+ private double screenHeight;
+ private double startZoom;
ScaleGestureListener(double densityMultiplier, float minimumGestureSpeed, float minimumAngledGestureSpeed,
float minimumVelocity) {
@@ -548,6 +554,9 @@ final class MapGestureDetector {
}
}
+ screenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
+ startZoom = transform.getRawZoom();
+
cancelTransitionsIfRequired();
notifyOnScaleBeginListeners(detector);
@@ -562,10 +571,24 @@ final class MapGestureDetector {
// dispatching camera start event only when the movement actually occurred
cameraChangeDispatcher.onCameraMoveStarted(CameraChangeDispatcher.REASON_API_GESTURE);
- float scaleFactor = detector.getScaleFactor();
- double zoomBy = getNewZoom(scaleFactor, quickZoom);
PointF focalPoint = getScaleFocalPoint(detector);
- transform.zoomBy(zoomBy, focalPoint);
+ if (quickZoom) {
+ double pixelDeltaChange = Math.abs(detector.getCurrentEvent().getY() - doubleTapFocalPoint.y);
+ boolean zoomedOut = detector.getCurrentEvent().getY() < doubleTapFocalPoint.y;
+
+ // normalize the pixel delta change, ranging from 0 to screen height, to a constant zoom change range
+ double normalizedDeltaChange = normalize(pixelDeltaChange, 0, screenHeight, 0, QUICK_ZOOM_MAX_ZOOM_CHANGE);
+
+ // calculate target zoom and adjust for a multiplier
+ double targetZoom = (zoomedOut ? startZoom - normalizedDeltaChange : startZoom + normalizedDeltaChange);
+ targetZoom *= uiSettings.getZoomRate();
+
+ transform.setZoom(targetZoom, focalPoint);
+ } else {
+ double zoomBy =
+ (Math.log(detector.getScaleFactor()) / Math.log(Math.PI / 2)) * ZOOM_RATE * uiSettings.getZoomRate();
+ transform.zoomBy(zoomBy, focalPoint);
+ }
notifyOnScaleListeners(detector);
@@ -628,19 +651,6 @@ final class MapGestureDetector {
}
return zoomAddition;
}
-
- private double getNewZoom(float scaleFactor, boolean quickZoom) {
- double zoomBy = (Math.log(scaleFactor) / Math.log(Math.PI / 2)) * ZOOM_RATE * uiSettings.getZoomRate();
- if (quickZoom) {
- // clamp scale factors we feed to core #7514
- boolean negative = zoomBy < 0;
- zoomBy = MathUtils.clamp(Math.abs(zoomBy),
- MapboxConstants.MINIMUM_SCALE_FACTOR_CLAMP,
- MapboxConstants.MAXIMUM_SCALE_FACTOR_CLAMP);
- return negative ? -zoomBy : zoomBy;
- }
- return zoomBy;
- }
}
private final class RotateGestureListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
index 0c90e4b244..7ec3262c57 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
@@ -46,4 +46,19 @@ public class MathUtils {
return secondMod + min;
}
+
+ /**
+ * Scale a value from an arbitrary range to a normalized range.
+ *
+ * @param x The value to be normalized.
+ * @param dataLow lowest expected value from a data set
+ * @param dataHigh highest expected value from a data set
+ * @param normalizedLow normalized lowest value
+ * @param normalizedHigh normalized highest value
+ * @return The result of the normalization.
+ */
+ public static double normalize(double x, double dataLow, double dataHigh,
+ double normalizedLow, double normalizedHigh) {
+ return ((x - dataLow) / (dataHigh - dataLow)) * (normalizedHigh - normalizedLow) + normalizedLow;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt
index 3980199cad..525c576df4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapGestureDetectorTest.kt
@@ -176,4 +176,18 @@ class MapGestureDetectorTest : BaseTest() {
Assert.assertNotEquals(initialCameraPosition!!.target.longitude, mapboxMap.cameraPosition.target.longitude, 1.0)
}
}
+
+ @Test
+ fun quickZoom_roundTripping() {
+ validateTestSetup()
+ rule.runOnUiThread {
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(51.0, 16.0), 3.0))
+ }
+ onView(withId(R.id.mapView)).perform(quickScale(300f, withVelocity = false, duration = 750L))
+ onView(withId(R.id.mapView)).perform(quickScale(-300f, withVelocity = false, duration = 750L))
+
+ rule.runOnUiThread {
+ Assert.assertEquals(3.0, mapboxMap.cameraPosition.zoom, 0.0001)
+ }
+ }
} \ No newline at end of file