summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Leege <bleege@gmail.com>2015-12-10 11:04:26 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-12-18 11:33:40 -0800
commitf7d1a40350c6c9b3eb9e0879b13619d4c7ad1373 (patch)
tree4ba564387e8087bd0501b549f7de06e30ef27e0c
parente2ad0e008a404b27314d4a2892d733f2f13656bf (diff)
downloadqtlocation-mapboxgl-f7d1a40350c6c9b3eb9e0879b13619d4c7ad1373.tar.gz
[android] Camera API
-rw-r--r--include/mbgl/map/camera.hpp10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java169
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java56
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java15
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java16
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java197
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/NativeMapView.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java172
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_transform_24dp.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera.xml51
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml7
-rw-r--r--platform/android/src/jni.cpp104
-rw-r--r--src/mbgl/map/transform.cpp19
17 files changed, 848 insertions, 15 deletions
diff --git a/include/mbgl/map/camera.hpp b/include/mbgl/map/camera.hpp
index dd9e0a0f56..184ee87464 100644
--- a/include/mbgl/map/camera.hpp
+++ b/include/mbgl/map/camera.hpp
@@ -12,11 +12,11 @@
namespace mbgl {
struct CameraOptions {
- mapbox::util::optional<LatLng> center;
- mapbox::util::optional<double> zoom;
- mapbox::util::optional<double> angle;
- mapbox::util::optional<double> pitch;
- mapbox::util::optional<Duration> duration;
+ mapbox::util::optional<LatLng> center; // Map center (Degrees)
+ mapbox::util::optional<double> zoom; // Map zoom level Positive Numbers > 0 and < 18
+ mapbox::util::optional<double> angle; // Map rotation bearing in Radians counter-clockwise from north. The value is wrapped to [−π rad, π rad]
+ mapbox::util::optional<double> pitch; // Map angle in degrees at which the camera is looking to ground (Radians)
+ mapbox::util::optional<Duration> duration; // Animation time length (Nanoseconds)
mapbox::util::optional<double> speed;
mapbox::util::optional<double> curve;
mapbox::util::optional<mbgl::util::UnitBezier> easing;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
new file mode 100644
index 0000000000..7b98a0df37
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
@@ -0,0 +1,169 @@
+package com.mapbox.mapboxsdk.camera;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.annotation.FloatRange;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+public final class CameraPosition implements Parcelable {
+
+ public static final Parcelable.Creator<CameraPosition> CREATOR
+ = new Parcelable.Creator<CameraPosition>() {
+ public CameraPosition createFromParcel(Parcel in) {
+ float bearing = in.readFloat();
+ LatLng target = in.readParcelable(LatLng.class.getClassLoader());
+ float tilt = in.readFloat();
+ float zoom = in.readFloat();
+ return new CameraPosition(target, zoom, tilt, bearing);
+ }
+
+ public CameraPosition[] newArray(int size) {
+ return new CameraPosition[size];
+ }
+ };
+
+
+ /**
+ * Direction that the camera is pointing in, in degrees clockwise from north.
+ */
+ public final float bearing;
+
+ /**
+ * The location that the camera is pointing at.
+ */
+ public final LatLng target;
+
+ /**
+ * The angle, in degrees, of the camera angle from the nadir (directly facing the Earth). See tilt(float) for details of restrictions on the range of values.
+ */
+ public final float tilt;
+
+ /**
+ * Zoom level near the center of the screen. See zoom(float) for the definition of the camera's zoom level.
+ */
+ public final float zoom;
+
+ /**
+ *
+ * Constructs a CameraPosition.
+ * @param target The target location to align with the center of the screen.
+ * @param zoom Zoom level at target. See zoom(float) for details of restrictions.
+ * @param tilt The camera angle, in degrees, from the nadir (directly down). See tilt(float) for details of restrictions.
+ * @param bearing Direction that the camera is pointing in, in degrees clockwise from north. This value will be normalized to be within 0 degrees inclusive and 360 degrees exclusive.
+ * @throws NullPointerException if target is null
+ * @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive.
+ */
+ public CameraPosition (LatLng target, float zoom, float tilt, float bearing) throws NullPointerException, IllegalArgumentException{
+ super();
+ if (target == null) {
+ throw new NullPointerException("target is NULL");
+ }
+ this.target = target;
+
+ // Allow for default value of -1
+ if (tilt != -1) {
+ if (tilt < 0.0f || tilt > 90.0f) {
+ throw new IllegalArgumentException("tilt is outside of 0 to 90 degrees range");
+ }
+ }
+ this.tilt = tilt;
+
+ this.bearing = bearing;
+ this.zoom = zoom;
+ }
+
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeFloat(bearing);
+ out.writeParcelable(target, flags);
+ out.writeFloat(tilt);
+ out.writeFloat(zoom);
+ }
+
+ /**
+ * Builds camera position.
+ */
+ public static final class Builder {
+
+ private float bearing = -1;
+ private LatLng target = null;
+ private float tilt = -1;
+ private float zoom = -1;
+
+ /**
+ * Creates an empty builder.
+ */
+ public Builder() {
+ super();
+ }
+
+ /**
+ * Create Builder with an existing CameraPosition data.
+ * @param previous Existing CameraPosition values to use
+ */
+ public Builder(CameraPosition previous) {
+ super();
+ if (previous != null) {
+ this.bearing = previous.bearing;
+ this.target = previous.target;
+ this.tilt = previous.tilt;
+ this.zoom = previous.zoom;
+ }
+ }
+
+ /**
+ * Sets the direction that the camera is pointing in, in degrees clockwise from north.
+ * @param bearing Bearing
+ * @return Builder
+ */
+ public Builder bearing (float bearing) {
+ this.bearing = bearing;
+ return this;
+ }
+
+ /**
+ * Builds a CameraPosition.
+ * @return CameraPosition
+ */
+ public CameraPosition build() {
+ return new CameraPosition(target, zoom, tilt, bearing);
+ }
+
+ /**
+ * Sets the location that the camera is pointing at.
+ * @param location Location
+ * @return Builder
+ */
+ public Builder target(LatLng location) {
+ this.target = location;
+ return this;
+ }
+
+ /**
+ * Set the tilt
+ * @param tilt Tilt value
+ * @return Builder
+ */
+ @FloatRange(from = 0.0, to = 60.0)
+ public Builder tilt(float tilt) {
+ this.tilt = tilt;
+ return this;
+ }
+
+ /**
+ * Set the zoom
+ * @param zoom Zoom value
+ * @return Builder
+ */
+ public Builder zoom(float zoom) {
+ this.zoom = zoom;
+ return this;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
new file mode 100644
index 0000000000..33f551550b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
@@ -0,0 +1,56 @@
+package com.mapbox.mapboxsdk.camera;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+public final class CameraUpdate {
+
+ /**
+ * Direction that the camera is pointing in, in degrees clockwise from north.
+ */
+ private final float bearing;
+
+ /**
+ * The location that the camera is pointing at.
+ */
+ private final LatLng target;
+
+ /**
+ * The angle, in degrees, of the camera angle from the nadir (directly facing the Earth). See tilt(float) for details of restrictions on the range of values.
+ */
+ private final float tilt;
+
+ /**
+ * Zoom level near the center of the screen. See zoom(float) for the definition of the camera's zoom level.
+ */
+ private final float zoom;
+
+ /**
+ * Package Private Constructor to only be used CameraUpdateFactory
+ * @param bearing Final Bearing
+ * @param target Final Target
+ * @param tilt Final Tilt
+ * @param zoom Final Zoom
+ */
+ CameraUpdate(float bearing, LatLng target, float tilt, float zoom) {
+ this.bearing = bearing;
+ this.target = target;
+ this.tilt = tilt;
+ this.zoom = zoom;
+ }
+
+ public float getBearing() {
+ return bearing;
+ }
+
+ public LatLng getTarget() {
+ return target;
+ }
+
+ public float getTilt() {
+ return tilt;
+ }
+
+ public float getZoom() {
+ return zoom;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
new file mode 100644
index 0000000000..3ba2090bd2
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
@@ -0,0 +1,15 @@
+package com.mapbox.mapboxsdk.camera;
+
+import android.support.annotation.NonNull;
+
+public class CameraUpdateFactory {
+
+ /**
+ * Returns a CameraUpdate that moves the camera to a specified CameraPosition.
+ * @param cameraPosition Camera Position to change to
+ * @return CameraUpdate Final Camera Position data
+ */
+ public static CameraUpdate newCameraPosition (@NonNull CameraPosition cameraPosition) {
+ return new CameraUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
+ }
+}
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
new file mode 100644
index 0000000000..4169577bd5
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
@@ -0,0 +1,16 @@
+package com.mapbox.mapboxsdk.utils;
+
+public class MathUtils {
+
+ /**
+ * Test a value in specified range, returning minimum if it's below, and maximum if it's above
+ * @param value Value to test
+ * @param min Minimum value of range
+ * @param max Maximum value of range
+ * @return value if it's between min and max, min if it's below, max if it's above
+ */
+ public static double clamp(double value, double min, double max) {
+ return Math.max(min, Math.min(max, value));
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index 67ac9c48f3..30127d4c37 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -65,6 +65,9 @@ import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.annotations.Sprite;
import com.mapbox.mapboxsdk.annotations.SpriteFactory;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.constants.MathConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
@@ -76,7 +79,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngZoom;
import com.mapbox.mapboxsdk.layers.CustomLayer;
import com.mapbox.mapboxsdk.utils.ApiAccess;
-
+import com.mapbox.mapboxsdk.utils.MathUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
@@ -84,6 +87,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.TimeUnit;
/**
* <p>
@@ -581,6 +585,21 @@ public final class MapView extends FrameLayout {
void onMyLocationChange(@Nullable Location location);
}
+ /**
+ * A callback interface for reporting when a task is complete or cancelled.
+ */
+ public static interface CancelableCallback {
+ /**
+ * Invoked when a task is cancelled.
+ */
+ public abstract void onCancel();
+
+ /**
+ * Invoked when a task is complete.
+ */
+ public abstract void onFinish();
+ }
+
//
// Constructors
//
@@ -1452,6 +1471,109 @@ public final class MapView extends FrameLayout {
this.mTiltEnabled = tiltEnabled;
}
+
+ //
+ // Camera API
+ //
+
+ /**
+ * Gets the current position of the camera.
+ * The CameraPosition returned is a snapshot of the current position, and will not automatically update when the camera moves.
+ * @return The current position of the Camera.
+ */
+ public final CameraPosition getCameraPosition () {
+ return new CameraPosition(getCenterCoordinate(), (float)getZoomLevel(), (float)getTilt(), (float)getBearing());
+ }
+
+ /**
+ * Animates the movement of the camera from the current position to the position defined in the update.
+ * During the animation, a call to getCameraPosition() returns an intermediate location of the camera.
+
+ * See CameraUpdateFactory for a set of updates.
+ * @param update The change that should be applied to the camera.
+ */
+ @UiThread
+ public final void animateCamera (CameraUpdate update) {
+ animateCamera(update, 0, null);
+ }
+
+
+ /**
+ * Animates the movement of the camera from the current position to the position defined in the update and calls an optional callback on completion.
+ * See CameraUpdateFactory for a set of updates.
+ * During the animation, a call to getCameraPosition() returns an intermediate location of the camera.
+ * @param update The change that should be applied to the camera.
+ * @param callback The callback to invoke from the main thread when the animation stops. If the animation completes normally, onFinish() is called; otherwise, onCancel() is called. Do not update or animate the camera from within onCancel().
+ */
+ @UiThread
+ public final void animateCamera (CameraUpdate update, MapView.CancelableCallback callback) {
+ animateCamera(update, 0, callback);
+ }
+
+ /**
+ * Moves the map according to the update with an animation over a specified duration, and calls an optional callback on completion. See CameraUpdateFactory for a set of updates.
+ * If getCameraPosition() is called during the animation, it will return the current location of the camera in flight.
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly positive, otherwise an IllegalArgumentException will be thrown.
+ * @param callback An optional callback to be notified from the main thread when the animation stops. If the animation stops due to its natural completion, the callback will be notified with onFinish(). If the animation stops due to interruption by a later camera movement or a user gesture, onCancel() will be called. The callback should not attempt to move or animate the camera in its cancellation method. If a callback isn't required, leave it as null.
+ */
+ @UiThread
+ public final void animateCamera (CameraUpdate update, int durationMs, final MapView.CancelableCallback callback) {
+
+ if (update.getTarget() == null) {
+ Log.w(TAG, "animateCamera with null target coordinate passed in. Will immediatele return without animating camera.");
+ return;
+ }
+
+ mNativeMapView.cancelTransitions();
+
+ // Register callbacks early enough
+ if (callback != null) {
+ final MapView view = this;
+ addOnMapChangedListener(new OnMapChangedListener() {
+ @Override
+ public void onMapChanged(@MapChange int change) {
+ if (change == REGION_DID_CHANGE_ANIMATED || change == REGION_DID_CHANGE) {
+ callback.onFinish();
+
+ // Clean up after self
+ removeOnMapChangedListener(this);
+ }
+ }
+ });
+ }
+
+ // Convert Degrees To Radians
+ double angle = -1;
+ if (update.getBearing() >= 0) {
+ angle = (-update.getBearing()) * MathConstants.DEG2RAD;
+ }
+ double pitch = -1;
+ if (update.getTilt() >= 0) {
+ double dp = MathUtils.clamp(update.getTilt(), MINIMUM_TILT, MAXIMUM_TILT);
+ pitch = dp * MathConstants.DEG2RAD;
+ }
+ double zoom = -1;
+ if (update.getZoom() >= 0) {
+ zoom = update.getZoom();
+ }
+
+ long durationNano = 0;
+ if (durationMs > 0) {
+ durationNano = TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS);
+ }
+
+ if (durationMs == 0) {
+ // Route To `jumpTo`
+ Log.i(TAG, "jumpTo() called with angle = " + angle + "; target = " + update.getTarget() + "; durationNano = " + durationNano + "; Pitch = " + pitch + "; Zoom = " + update.getZoom());
+ jumpTo(angle, update.getTarget(), pitch, zoom);
+ } else {
+ // Use `flyTo`
+ Log.i(TAG, "flyTo() called with angle = " + angle + "; target = " + update.getTarget() + "; durationNano = " + durationNano + "; Pitch = " + pitch + "; Zoom = " + update.getZoom());
+ flyTo(angle, update.getTarget(), durationNano, pitch, zoom);
+ }
+ }
+
//
// InfoWindows
//
@@ -2276,10 +2398,52 @@ public final class MapView extends FrameLayout {
}
//
- // Camera
+ // Mapbox Core GL Camera
//
/**
+ * Change any combination of center, zoom, bearing, and pitch, without
+ * a transition. The map will retain the current values for any options
+ * not included in `options`.
+ * @param bearing Bearing in Radians
+ * @param center Center Coordinate
+ * @param pitch Pitch in Radians
+ * @param zoom Zoom Level
+ */
+ @UiThread
+ public void jumpTo(double bearing, LatLng center, double pitch, double zoom) {
+ mNativeMapView.jumpTo(bearing, center, pitch, zoom);
+ }
+
+ /**
+ * Change any combination of center, zoom, bearing, and pitch, with a smooth animation
+ * between old and new values. The map will retain the current values for any options
+ * not included in `options`.
+ * @param bearing Bearing in Radians
+ * @param center Center Coordinate
+ * @param duration Animation time in Nanoseconds
+ * @param pitch Pitch in Radians
+ * @param zoom Zoom Level
+ */
+ @UiThread
+ public void easeTo(double bearing, LatLng center, long duration, double pitch, double zoom) {
+ mNativeMapView.easeTo(bearing, center, duration, pitch, zoom);
+ }
+
+ /**
+ * Flying animation to a specified location/zoom/bearing with automatic curve.
+ * @param bearing Bearing in Radians
+ * @param center Center Coordinate
+ * @param duration Animation time in Nanoseconds
+ * @param pitch Pitch in Radians
+ * @param zoom Zoom Level
+ */
+ @UiThread
+ public void flyTo(double bearing, LatLng center, long duration, double pitch, double zoom) {
+ mNativeMapView.flyTo(bearing, center, duration, pitch, zoom);
+ }
+
+ /**
* Changes the map's viewport to fit the given coordinate bounds.
*
* @param bounds The bounds that the viewport will show in its entirety.
@@ -2464,9 +2628,32 @@ public final class MapView extends FrameLayout {
}
}
- // Used by UserLocationView
- void setBearing(float bearing) {
- mNativeMapView.setBearing(bearing, 100);
+ /**
+ * Get Bearing in degrees
+ * @return Bearing in degrees
+ */
+ public double getBearing() {
+ return mNativeMapView.getBearing();
+ }
+
+ /**
+ * Set Bearing in degrees
+ * @param bearing Bearing in degrees
+ */
+ public void setBearing(float bearing) {
+ mNativeMapView.setBearing(bearing);
+ }
+
+ /**
+ * Sets Bearing in degrees
+ *
+ * NOTE: Used by UserLocationView
+ *
+ * @param bearing Bearing in degrees
+ * @param duration Length of time to rotate
+ */
+ public void setBearing(float bearing, long duration) {
+ mNativeMapView.setBearing(bearing, duration);
}
//
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/NativeMapView.java
index dd6b9cf7eb..6df0defe35 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/NativeMapView.java
@@ -3,7 +3,6 @@ package com.mapbox.mapboxsdk.views;
import android.graphics.PointF;
import android.graphics.RectF;
import android.view.Surface;
-
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.Polyline;
@@ -12,7 +11,6 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngZoom;
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
import com.mapbox.mapboxsdk.layers.CustomLayer;
-
import java.lang.ref.WeakReference;
import java.util.List;
@@ -450,6 +448,18 @@ final class NativeMapView {
return nativeGetTopOffsetPixelsForAnnotationSymbol(mNativeMapViewPtr, symbolName);
}
+ public void jumpTo(double angle, LatLng center, double pitch, double zoom) {
+ nativeJumpTo(mNativeMapViewPtr, angle, center, pitch, zoom);
+ }
+
+ public void easeTo(double angle, LatLng center, long duration, double pitch, double zoom) {
+ nativeEaseTo(mNativeMapViewPtr, angle, center, duration, pitch, zoom);
+ }
+
+ public void flyTo(double angle, LatLng center, long duration, double pitch, double zoom) {
+ nativeFlyTo(mNativeMapViewPtr, angle, center, duration, pitch, zoom);
+ }
+
public void addCustomLayer(CustomLayer customLayer, String before) {
nativeAddCustomLayer(mNativeMapViewPtr, customLayer, before);
}
@@ -639,6 +649,12 @@ final class NativeMapView {
private native double nativeGetTopOffsetPixelsForAnnotationSymbol(long nativeMapViewPtr, String symbolName);
+ private native void nativeJumpTo(long nativeMapViewPtr, double angle, LatLng center, double pitch, double zoom);
+
+ private native void nativeEaseTo(long nativeMapViewPtr, double angle, LatLng center, long duration, double pitch, double zoom);
+
+ private native void nativeFlyTo(long nativeMapViewPtr, double angle, LatLng center, long duration, double pitch, double zoom);
+
private native void nativeAddCustomLayer(long nativeMapViewPtr, CustomLayer customLayer, String before);
private native void nativeRemoveCustomLayer(long nativeMapViewPtr, String id);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
index ba48eb574f..47339ed297 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
@@ -91,6 +91,7 @@ final class UserLocationView extends View implements LocationListener {
// Compass data
private MyBearingListener mBearingChangeListener;
+ private static final long BEARING_DURATION = 100;
public UserLocationView(Context context) {
super(context);
@@ -555,7 +556,7 @@ final class UserLocationView extends View implements LocationListener {
mShowDirection = true;
mGpsMarkerDirection = 0;
if (location.hasBearing()) {
- mMapView.setBearing(location.getBearing());
+ mMapView.setBearing(location.getBearing(), BEARING_DURATION);
}
}
@@ -602,7 +603,7 @@ final class UserLocationView extends View implements LocationListener {
mShowDirection = true;
mGpsMarkerDirection = 0;
mCompassMarkerDirection = 0;
- mMapView.setBearing(bearing);
+ mMapView.setBearing(bearing, BEARING_DURATION);
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 44ebc8c949..3188d717a1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -37,7 +37,9 @@
<activity
android:name=".BulkMarkerActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
- android:label="@string/action_add_bulk_markers" />
+ android:label="@string/activity_add_bulk_markers" />
+ <activity android:name=".CameraActivity"
+ android:label="@string/activity_camera"/>
<activity
android:name=".TiltActivity"
android:label="@string/activity_tilt" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java
new file mode 100644
index 0000000000..5bd03da1df
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/CameraActivity.java
@@ -0,0 +1,172 @@
+package com.mapbox.mapboxsdk.testapp;
+
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.util.Log;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.utils.ApiAccess;
+import com.mapbox.mapboxsdk.views.MapView;
+
+public class CameraActivity extends AppCompatActivity {
+
+ private static final String TAG = "CameraActivity";
+
+ private MapView mMapView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_camera);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mMapView = (MapView) findViewById(R.id.cameraMapView);
+ mMapView.setAccessToken(ApiAccess.getToken(this));
+ mMapView.setStyle(Style.MAPBOX_STREETS);
+ mMapView.setCompassEnabled(true);
+ mMapView.onCreate(savedInstanceState);
+
+ Button cameraButton = (Button) findViewById(R.id.cameraAnimateButton);
+ cameraButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(new LatLng(44.50128, -88.06216)) // Sets the center of the map to Lambeau Field
+ .zoom(14) // Sets the zoom
+ .tilt(30) // Sets the tilt of the camera to 30 degrees
+ .build(); // Creates a CameraPosition from the builder
+ mMapView.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
+ }
+ });
+
+ Button cameraCallbackButton = (Button) findViewById(R.id.cameraAnimateCallbackButton);
+ cameraCallbackButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(new LatLng(48.21874, 11.62465)) // Sets the center of the map to Allianz Arena
+ .zoom(16) // Sets the zoom
+ .bearing(180) // Sets the orientation of the camera to south
+ .build(); // Creates a CameraPosition from the builder
+
+ MapView.CancelableCallback callback = new MapView.CancelableCallback() {
+ @Override
+ public void onCancel() {
+ // NOTE: This shouldn't appear
+ Log.i(TAG, "onCancel Callback called.");
+ Toast.makeText(CameraActivity.this, "onCancel Callback called.", Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onFinish() {
+ Log.i(TAG, "onFinish Callback called.");
+ Toast.makeText(CameraActivity.this, "onFinish Callback called.", Toast.LENGTH_LONG).show();
+ }
+ };
+
+ mMapView.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), callback);
+
+ }
+ });
+
+ Button cameraDurationButton = (Button) findViewById(R.id.cameraAnimateDurationButton);
+ cameraDurationButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(new LatLng(-22.91214, -43.23012)) // Sets the center of the map to Maracanã
+ .bearing(270) // Sets the orientation of the camera to west
+ .tilt(20) // Sets the tilt of the camera to 30 degrees
+ .build(); // Creates a CameraPosition from the builder
+
+ MapView.CancelableCallback callback = new MapView.CancelableCallback() {
+ @Override
+ public void onCancel() {
+ Log.i(TAG, "Duration onCancel Callback called.");
+ Toast.makeText(CameraActivity.this, "Duration onCancel Callback called.", Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onFinish() {
+ Log.i(TAG, "Duration onFinish Callback called.");
+ Toast.makeText(CameraActivity.this, "Duration onFinish Callback called.", Toast.LENGTH_LONG).show();
+ }
+ };
+
+ mMapView.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 25000, callback);
+ }
+ });
+
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mMapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mMapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mMapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mMapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mMapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mMapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mMapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
index 6bfaf8fa60..7199eae997 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
@@ -342,6 +342,10 @@ public class MainActivity extends AppCompatActivity {
startActivity(new Intent(getApplicationContext(), InfoWindowAdapterActivity.class));
return true;
+ case R.id.action_camera:
+ startActivity(new Intent(getApplicationContext(), CameraActivity.class));
+ return true;
+
case R.id.action_tilt:
startActivity(new Intent(getApplicationContext(), TiltActivity.class));
return true;
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_transform_24dp.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_transform_24dp.xml
new file mode 100644
index 0000000000..b8448abb14
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_transform_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFF"
+ android:pathData="M22,18v-2H8V4h2L7,1 4,4h2v2H2v2h4v8c0,1.1 0.9,2 2,2h8v2h-2l3,3 3,-3h-2v-2h4zM10,8h6v6h2V8c0,-1.1 -0.9,-2 -2,-2h-6v2z"/>
+</vector>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera.xml
new file mode 100644
index 0000000000..86e7199f77
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+ <com.mapbox.mapboxsdk.views.MapView
+ android:id="@+id/cameraMapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@+id/toolbar"/>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_camera_animate"
+ android:id="@+id/cameraAnimateButton"
+ android:layout_margin="@dimen/fab_margin"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true"
+ android:layout_alignParentBottom="true"
+ android:background="@color/white"/>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_camera_animate_callback"
+ android:id="@+id/cameraAnimateCallbackButton"
+ android:layout_alignTop="@+id/cameraAnimateButton"
+ android:layout_centerHorizontal="true"
+ android:background="@color/white"/>
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_camera_animate_duration"
+ android:id="@+id/cameraAnimateDurationButton"
+ android:layout_alignBottom="@+id/cameraAnimateCallbackButton"
+ android:layout_alignParentRight="true"
+ android:layout_marginRight="@dimen/fab_margin"
+ android:background="@color/white"/>
+
+</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
index 9a81182837..67c4336481 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_drawer.xml
@@ -72,6 +72,11 @@
android:icon="@drawable/ic_tilt"
android:title="@string/action_tilt" />
+ <item android:id="@+id/action_camera"
+ android:checkable="false"
+ android:icon="@drawable/ic_transform_24dp"
+ android:title="@string/action_camera"/>
+
<item
android:id="@+id/action_map_fragment"
android:checkable="false"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 10d622d38f..ab28c93e3f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -14,6 +14,8 @@
<string name="activity_info_window_concurrent">InfoWindow Activity (Concurrent)</string>
<string name="activity_visible_coordinate_bounds">Visible Coordinate Bounds</string>
<string name="activity_user_tracking_mode">User tracking mode</string>
+ <string name="activity_add_bulk_markers">Add Markers In Bulk</string>
+ <string name="activity_camera">Camera</string>
<string name="activity_polyline">Polyline Activity</string>
<string name="activity_animate_coordinate_change">Animate Coordinate Change</string>
<string name="activity_custom_layer">Custom Layer</string>
@@ -35,10 +37,15 @@
<string name="action_animate_coordinate_change">Animate Coordinate Change</string>
<string name="action_info_window_concurrent">InfoWindow (Concurrent)</string>
<string name="action_add_bulk_markers">Add Markers in bulk</string>
+ <string name="action_camera">Camera</string>
<string name="action_visible_bounds">Set Visible Bounds</string>
<string name="action_visible_bounds_explanation">Center map around 2 markers</string>
<string name="action_remove_polylines">Remove polylines</string>
+ <string name="button_camera_animate">Animate</string>
+ <string name="button_camera_animate_callback">Callback</string>
+ <string name="button_camera_animate_duration">Duration</string>
+
<string name="label_fps">FPS:</string>
<string name="styleMapboxStreets">Mapbox Streets</string>
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index f99b733598..4005a65817 100644
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -1479,6 +1479,104 @@ jdouble JNICALL nativeGetTopOffsetPixelsForAnnotationSymbol(JNIEnv *env, jobject
return nativeMapView->getMap().getTopOffsetPixelsForAnnotationIcon(std_string_from_jstring(env, symbolName));
}
+void JNICALL nativeJumpTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle, jobject centerLatLng, jdouble pitch, jdouble zoom) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeJumpTo");
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+
+ jdouble latitude = env->GetDoubleField(centerLatLng, latLngLatitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ return;
+ }
+
+ jdouble longitude = env->GetDoubleField(centerLatLng, latLngLongitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ return;
+ }
+
+ mbgl::CameraOptions options;
+ if (angle != -1) {
+ options.angle = angle;
+ }
+ options.center = mbgl::LatLng(latitude, longitude);
+ if (pitch != -1) {
+ options.pitch = pitch;
+ }
+ if (zoom != -1) {
+ options.zoom = zoom;
+ }
+
+ nativeMapView->getMap().jumpTo(options);
+}
+
+void JNICALL nativeEaseTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle, jobject centerLatLng, jlong duration, jdouble pitch, jdouble zoom) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeEaseTo");
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+
+ jdouble latitude = env->GetDoubleField(centerLatLng, latLngLatitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ return;
+ }
+
+ jdouble longitude = env->GetDoubleField(centerLatLng, latLngLongitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ return;
+ }
+
+ mbgl::CameraOptions options;
+ if (angle != -1) {
+ options.angle = angle;
+ }
+ options.center = mbgl::LatLng(latitude, longitude);
+ options.duration = mbgl::Duration(duration);
+ if (pitch != -1) {
+ options.pitch = pitch;
+ }
+ if (zoom != -1) {
+ options.zoom = zoom;
+ }
+
+ nativeMapView->getMap().easeTo(options);
+}
+
+void JNICALL nativeFlyTo(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble angle, jobject centerLatLng, jlong duration, jdouble pitch, jdouble zoom) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeFlyTo");
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+
+ jdouble latitude = env->GetDoubleField(centerLatLng, latLngLatitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ return;
+ }
+
+ jdouble longitude = env->GetDoubleField(centerLatLng, latLngLongitudeId);
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ return;
+ }
+
+ mbgl::CameraOptions options;
+ if (angle != -1) {
+ options.angle = angle;
+ }
+ options.center = mbgl::LatLng(latitude, longitude);
+ options.duration = mbgl::Duration(duration);
+ if (pitch != -1) {
+ options.pitch = pitch;
+ }
+ if (zoom != -1) {
+ options.zoom = zoom;
+ }
+
+ nativeMapView->getMap().flyTo(options);
+}
+
void JNICALL nativeAddCustomLayer(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject customLayer, jstring before) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddCustomLayer");
assert(nativeMapViewPtr != 0);
@@ -2022,6 +2120,12 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
reinterpret_cast<void *>(&nativeLatLngForPixel)},
{"nativeGetTopOffsetPixelsForAnnotationSymbol", "(JLjava/lang/String;)D",
reinterpret_cast<void *>(&nativeGetTopOffsetPixelsForAnnotationSymbol)},
+ {"nativeJumpTo", "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;DD)V",
+ reinterpret_cast<void *>(&nativeJumpTo)},
+ {"nativeEaseTo", "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;JDD)V",
+ reinterpret_cast<void *>(&nativeEaseTo)},
+ {"nativeFlyTo", "(JDLcom/mapbox/mapboxsdk/geometry/LatLng;JDD)V",
+ reinterpret_cast<void *>(&nativeFlyTo)},
{"nativeAddCustomLayer", "(JLcom/mapbox/mapboxsdk/layers/CustomLayer;Ljava/lang/String;)V",
reinterpret_cast<void *>(&nativeAddCustomLayer)},
{"nativeRemoveCustomLayer", "(JLjava/lang/String;)V",
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 58541ccfaf..d15955abcf 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -7,6 +7,7 @@
#include <mbgl/util/unitbezier.hpp>
#include <mbgl/util/interpolate.hpp>
#include <mbgl/util/tile_coordinate.hpp>
+#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
#include <cstdio>
@@ -61,12 +62,22 @@ bool Transform::resize(const std::array<uint16_t, 2> size) {
#pragma mark - Position
+/*
+ * Change any combination of center, zoom, bearing, and pitch, without
+ * a transition. The map will retain the current values for any options
+ * not included in `options`.
+ */
void Transform::jumpTo(const CameraOptions& options) {
CameraOptions jumpOptions(options);
jumpOptions.duration.reset();
easeTo(jumpOptions);
}
+/*
+ * Change any combination of center, zoom, bearing, and pitch, with a smooth animation
+ * between old and new values. The map will retain the current values for any options
+ * not included in `options`.
+ */
void Transform::easeTo(const CameraOptions& options) {
CameraOptions easeOptions(options);
LatLng latLng = easeOptions.center ? *easeOptions.center : getLatLng();
@@ -313,18 +324,24 @@ void Transform::_easeTo(const CameraOptions& options, double new_scale, double n
}
}
+/**
+* Flying animation to a specified location/zoom/bearing with automatic curve.
+*/
void Transform::flyTo(const CameraOptions &options) {
+
CameraOptions flyOptions(options);
LatLng latLng = options.center ? *options.center : getLatLng();
LatLng startLatLng = getLatLng();
double zoom = flyOptions.zoom ? *flyOptions.zoom : getZoom();
double angle = flyOptions.angle ? *flyOptions.angle : getAngle();
double pitch = flyOptions.pitch ? *flyOptions.pitch : getPitch();
+
if (std::isnan(latLng.latitude) || std::isnan(latLng.longitude) || std::isnan(zoom)) {
return;
}
double new_scale = std::pow(2.0, zoom);
+ mbgl::Log::Info(mbgl::Event::JNI, "flyTo - new_scale: %f", new_scale);
const double scaled_tile_size = new_scale * util::tileSize;
state.Bc = scaled_tile_size / 360;
@@ -344,6 +361,8 @@ void Transform::flyTo(const CameraOptions &options) {
state.panning = true;
state.scaling = true;
state.rotating = true;
+
+ mbgl::Log::Info(mbgl::Event::JNI, "flyTo - startZ: %f", startZ);
double rho = flyOptions.curve ? *flyOptions.curve : 1.42;
double w0 = std::max(state.width, state.height);