diff options
23 files changed, 832 insertions, 1112 deletions
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 9d3c40b63b..5721df229a 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -5,6 +5,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to ## master ### Features - Introduce `clusterProperties` option for aggregated cluster properties. [#15425](https://github.com/mapbox/mapbox-gl-native/pull/15425) + - Expose the `CameraPosition#padding` field and associated utility camera position builders. This gives a choice to set a persisting map padding immediately during a transition instead of setting it lazily `MapboxMap#setPadding`, which required scheduling additional transition to be applied. This also deprecates `MapboxMap#setPadding` as there should be no need for a lazy padding setter. [#15444](https://github.com/mapbox/mapbox-gl-native/pull/15444) ## 8.3.0 - August 28, 2019 [Changes](https://github.com/mapbox/mapbox-gl-native/compare/android-v8.3.0-beta.1...android-v8.3.0) since [Mapbox Maps SDK for Android v8.3.0-beta.1](https://github.com/mapbox/mapbox-gl-native/releases/tag/android-v8.3.0-beta.1): 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 index f44c0f1904..e2341029ff 100644 --- 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 @@ -5,20 +5,23 @@ import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.FloatRange; import android.support.annotation.Keep; - import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.Size; + import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.utils.MathUtils; +import java.util.Arrays; + /** * Resembles the position, angle, zoom and tilt of the user's viewpoint. */ public final class CameraPosition implements Parcelable { - public static final CameraPosition DEFAULT = new CameraPosition(new LatLng(), 0, 0, 0); + public static final CameraPosition DEFAULT = new CameraPosition(new LatLng(), 0, 0, 0, new double[] {0, 0, 0, 0}); public static final Parcelable.Creator<CameraPosition> CREATOR = new Parcelable.Creator<CameraPosition>() { @@ -27,7 +30,9 @@ public final class CameraPosition implements Parcelable { LatLng target = in.readParcelable(LatLng.class.getClassLoader()); double tilt = in.readDouble(); double zoom = in.readDouble(); - return new CameraPosition(target, zoom, tilt, bearing); + double[] padding = new double[4]; + in.readDoubleArray(padding); + return new CameraPosition(target, zoom, tilt, bearing, padding); } public CameraPosition[] newArray(int size) { @@ -49,19 +54,26 @@ public final class CameraPosition implements Parcelable { /** * 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. + * See {@link Builder#tilt(double)} for details of restrictions on the range of values. */ @Keep public final double tilt; /** - * Zoom level near the center of the screen. See zoom(float) for the definition of the camera's + * Zoom level near the center of the screen. See {@link Builder#zoom(double)} for the definition of the camera's * zoom level. */ @Keep public final double zoom; /** + * Padding in pixels. Specified in left, top, right, bottom order. + * See {@link Builder#padding(double[])} for the definition of the camera's padding. + */ + @Keep + public final double[] padding; + + /** * Constructs a CameraPosition. * * @param target The target location to align with the center of the screen. @@ -73,13 +85,34 @@ public final class CameraPosition implements Parcelable { * exclusive. * @throws NullPointerException if target is null * @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive. + * @deprecated use {@link CameraPosition#CameraPosition(LatLng, double, double, double, double[])} instead. */ - @Keep + @Deprecated CameraPosition(LatLng target, double zoom, double tilt, double bearing) { + this(target, zoom, tilt, bearing, null); + } + + /** + * 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. + * @param padding Padding in pixels. Specified in left, top, right, bottom order. + * @throws NullPointerException if target is null + * @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive. + */ + @Keep + CameraPosition(LatLng target, double zoom, double tilt, double bearing, double[] padding) { this.target = target; this.bearing = bearing; this.tilt = tilt; this.zoom = zoom; + this.padding = padding; } /** @@ -106,6 +139,7 @@ public final class CameraPosition implements Parcelable { out.writeParcelable(target, flags); out.writeDouble(tilt); out.writeDouble(zoom); + out.writeDoubleArray(padding); } /** @@ -115,7 +149,8 @@ public final class CameraPosition implements Parcelable { */ @Override public String toString() { - return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt; + return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt + + ", Padding:" + Arrays.toString(padding); } /** @@ -145,6 +180,8 @@ public final class CameraPosition implements Parcelable { return false; } else if (bearing != cameraPosition.bearing) { return false; + } else if (!Arrays.equals(padding, cameraPosition.padding)) { + return false; } return true; } @@ -159,8 +196,16 @@ public final class CameraPosition implements Parcelable { */ @Override public int hashCode() { - int result = 1; + int result; + long temp; + temp = Double.doubleToLongBits(bearing); + result = (int) (temp ^ (temp >>> 32)); result = 31 * result + (target != null ? target.hashCode() : 0); + temp = Double.doubleToLongBits(tilt); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(zoom); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + result = 31 * result + Arrays.hashCode(padding); return result; } @@ -174,6 +219,7 @@ public final class CameraPosition implements Parcelable { private LatLng target = null; private double tilt = -1; private double zoom = -1; + private double[] padding = null; /** * Create an empty builder. @@ -194,6 +240,7 @@ public final class CameraPosition implements Parcelable { this.target = previous.target; this.tilt = previous.tilt; this.zoom = previous.zoom; + this.padding = previous.padding; } } @@ -226,6 +273,7 @@ public final class CameraPosition implements Parcelable { target = update.getTarget(); tilt = update.getTilt(); zoom = update.getZoom(); + padding = update.getPadding(); } } @@ -307,12 +355,43 @@ public final class CameraPosition implements Parcelable { } /** + * Padding in pixels that shifts the viewport by the specified amount. + * Applied padding is going to persist and impact following camera transformations. + * <p> + * Specified in left, top, right, bottom order. + * </p> + * + * @param padding Camera padding + * @return this + */ + @NonNull + public Builder padding(@Size(4) double[] padding) { + this.padding = padding; + return this; + } + + /** + * Padding in pixels that shifts the viewport by the specified amount. + * Applied padding is going to persist and impact following camera transformations. + * <p> + * Specified in left, top, right, bottom order. + * </p> + * + * @return this + */ + @NonNull + public Builder padding(double left, double top, double right, double bottom) { + this.padding = new double[] {left, top, right, bottom}; + return this; + } + + /** * Builds the CameraPosition. * * @return CameraPosition */ public CameraPosition build() { - return new CameraPosition(target, zoom, tilt, bearing); + return new CameraPosition(target, zoom, tilt, bearing, padding); } } } 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 index 16285468ee..b611456f43 100644 --- 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 @@ -5,6 +5,7 @@ import android.graphics.PointF; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; + import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -28,7 +29,7 @@ public final class CameraUpdateFactory { */ public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) { return new CameraPositionUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, - cameraPosition.zoom); + cameraPosition.zoom, cameraPosition.padding); } /** @@ -39,7 +40,7 @@ public final class CameraUpdateFactory { * @return CameraUpdate Final Camera Position */ public static CameraUpdate newLatLng(@NonNull LatLng latLng) { - return new CameraPositionUpdate(-1, latLng, -1, -1); + return new CameraPositionUpdate(-1, latLng, -1, -1, null); } /** @@ -48,6 +49,7 @@ public final class CameraUpdateFactory { * current camera position bearing and tilt values. * <p> * You can specify padding, in order to inset the bounding box from the map view's edges. + * The padding will not persist and impact following camera transformations. * </p> * * @param bounds Bounds to match Camera position with @@ -64,6 +66,7 @@ public final class CameraUpdateFactory { * provided bearing and tilt values. * <p> * You can specify padding, in order to inset the bounding box from the map view's edges. + * The padding will not persist and impact following camera transformations. * </p> * * @param bounds Bounds to match Camera position with @@ -82,6 +85,7 @@ public final class CameraUpdateFactory { * current camera position bearing and tilt values. * <p> * You can specify padding, in order to inset the bounding box from the map view's edges. + * The padding will not persist and impact following camera transformations. * </p> * * @param bounds Bounds to base the Camera position out of @@ -102,6 +106,7 @@ public final class CameraUpdateFactory { * provided bearing and tilt values. * <p> * You can specify padding, in order to inset the bounding box from the map view's edges. + * The padding will not persist and impact following camera transformations. * </p> * * @param bounds Bounds to base the Camera position out of @@ -120,14 +125,31 @@ public final class CameraUpdateFactory { /** * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude - * specified by a LatLng object, and moves to the given zoom level. + * specified by a LatLng object taking the specified padding into account. * * @param latLng Target location to change to * @param zoom Zoom level to change to * @return CameraUpdate Final Camera Position */ public static CameraUpdate newLatLngZoom(@NonNull LatLng latLng, double zoom) { - return new CameraPositionUpdate(-1, latLng, -1, zoom); + return new CameraPositionUpdate(-1, latLng, -1, zoom, null); + } + + /** + * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude + * specified by a LatLng object, and moves to the given zoom level. + * Applied padding is going to persist and impact following camera transformations. + * + * @param latLng Target location to change to + * @param left Left padding + * @param top Top padding + * @param right Right padding + * @param bottom Bottom padding + * @return CameraUpdate Final Camera Position + */ + public static CameraUpdate newLatLngPadding(@NonNull LatLng latLng, + double left, double top, double right, double bottom) { + return new CameraPositionUpdate(-1, latLng, -1, -1, new double[] {left, top, right, bottom}); } /** @@ -188,7 +210,7 @@ public final class CameraUpdateFactory { * @return CameraUpdate Final Camera Position */ public static CameraUpdate bearingTo(double bearing) { - return new CameraPositionUpdate(bearing, null, -1, -1); + return new CameraPositionUpdate(bearing, null, -1, -1, null); } /** @@ -198,7 +220,34 @@ public final class CameraUpdateFactory { * @return CameraUpdate Final Camera Position */ public static CameraUpdate tiltTo(double tilt) { - return new CameraPositionUpdate(-1, null, tilt, -1); + return new CameraPositionUpdate(-1, null, tilt, -1, null); + } + + /** + * Returns a CameraUpdate that when animated changes the camera padding. + * Applied padding is going to persist and impact following camera transformations. + * <p> + * Specified in left, top, right, bottom order. + * </p> + * + * @param padding Padding to change to + * @return CameraUpdate Final Camera Position + */ + public static CameraUpdate paddingTo(double[] padding) { + return new CameraPositionUpdate(-1, null, -1, -1, padding); + } + + /** + * Returns a CameraUpdate that when animated changes the camera padding. + * Applied padding is going to persist and impact following camera transformations. + * <p> + * Specified in left, top, right, bottom order. + * </p> + * + * @return CameraUpdate Final Camera Position + */ + public static CameraUpdate paddingTo(double left, double top, double right, double bottom) { + return paddingTo(new double[] {left, top, right, bottom}); } // @@ -211,12 +260,14 @@ public final class CameraUpdateFactory { private final LatLng target; private final double tilt; private final double zoom; + private final double[] padding; - CameraPositionUpdate(double bearing, LatLng target, double tilt, double zoom) { + CameraPositionUpdate(double bearing, LatLng target, double tilt, double zoom, double[] padding) { this.bearing = bearing; this.target = target; this.tilt = tilt; this.zoom = zoom; + this.padding = padding; } public LatLng getTarget() { @@ -235,10 +286,14 @@ public final class CameraUpdateFactory { return zoom; } + public double[] getPadding() { + return padding; + } + @Override public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) { - CameraPosition previousPosition = mapboxMap.getCameraPosition(); if (target == null) { + CameraPosition previousPosition = mapboxMap.getCameraPosition(); return new CameraPosition.Builder(this) .target(previousPosition.target) .build(); @@ -247,7 +302,7 @@ public final class CameraUpdateFactory { } @Override - public boolean equals(@Nullable Object o) { + public boolean equals(Object o) { if (this == o) { return true; } @@ -266,7 +321,10 @@ public final class CameraUpdateFactory { if (Double.compare(that.zoom, zoom) != 0) { return false; } - return target != null ? target.equals(that.target) : that.target == null; + if (target != null ? !target.equals(that.target) : that.target != null) { + return false; + } + return Arrays.equals(padding, that.padding); } @Override @@ -280,6 +338,7 @@ public final class CameraUpdateFactory { result = 31 * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(zoom); result = 31 * result + (int) (temp ^ (temp >>> 32)); + result = 31 * result + Arrays.hashCode(padding); return result; } @@ -290,6 +349,7 @@ public final class CameraUpdateFactory { + ", target=" + target + ", tilt=" + tilt + ", zoom=" + zoom + + ", padding=" + Arrays.toString(padding) + '}'; } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java index 8ab03e7acd..48c89622cd 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationComponentOptions.java @@ -1530,8 +1530,11 @@ public class LocationComponentOptions implements Parcelable { * </p> * * @param padding The margins for the map in pixels (left, top, right, bottom). + * @deprecated Use {@link CameraPosition.Builder#padding(double, double, double, double)} + * or {@link CameraUpdateFactory#paddingTo(double, double, double, double)} instead. */ @NonNull + @Deprecated public LocationComponentOptions.Builder padding(@Nullable int[] padding) { if (padding == null) { throw new NullPointerException("Null padding"); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 8e1019b379..acd5093dad 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -1540,24 +1540,38 @@ public final class MapboxMap { * frame from the viewport. For instance, if the only the top edge is inset, the * map center is effectively shifted downward. * </p> + * <p> + * This method sets the padding "lazily". + * This means that the <b>padding is going to be applied with the next camera transformation.</b> + * To apply the padding immediately use {@link CameraPosition.Builder#padding(double, double, double, double)} + * or {@link CameraUpdateFactory#paddingTo(double, double, double, double)}. + * </p> * * @param left The left margin in pixels. * @param top The top margin in pixels. * @param right The right margin in pixels. * @param bottom The bottom margin in pixels. + * @deprecated Use {@link CameraPosition.Builder#padding(double, double, double, double)} + * or {@link CameraUpdateFactory#paddingTo(double, double, double, double)} instead. */ + @Deprecated public void setPadding(int left, int top, int right, int bottom) { + // TODO padding should be passed as doubles projection.setContentPadding(new int[] {left, top, right, bottom}); uiSettings.invalidate(); } /** - * Returns the current configured content padding on map view. + * Returns the current configured content padding on map view. This might return the currently visible padding + * or the padding cached but not yet applied by {@link #setPadding(int, int, int, int)}. * * @return An array with length 4 in the LTRB order. + * @deprecated Use {@link CameraPosition#padding} instead. */ + @Deprecated @NonNull public int[] getPadding() { + // TODO this should return double[] (semver major change) return projection.getContentPadding(); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java index da70013713..7f3017c7ae 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMap.java @@ -41,12 +41,12 @@ interface NativeMap { // Camera API // - void jumpTo(@NonNull LatLng center, double zoom, double pitch, double bearing); + void jumpTo(@NonNull LatLng center, double zoom, double pitch, double bearing, double[] padding); - void easeTo(@NonNull LatLng center, double zoom, double bearing, double pitch, long duration, + void easeTo(@NonNull LatLng center, double zoom, double bearing, double pitch, double[] padding, long duration, boolean easingInterpolator); - void flyTo(@NonNull LatLng center, double zoom, double bearing, double pitch, long duration); + void flyTo(@NonNull LatLng center, double zoom, double bearing, double pitch, double[] padding, long duration); void moveBy(double deltaX, double deltaY, long duration); @@ -161,9 +161,9 @@ interface NativeMap { // Content padding API // - void setContentPadding(float[] padding); + void setContentPadding(double[] padding); - float[] getContentPadding(); + double[] getContentPadding(); // // Query API diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index fc68a408fa..8496160c7e 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -10,6 +10,7 @@ import android.support.annotation.Keep; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; + import com.mapbox.geojson.Feature; import com.mapbox.geojson.Geometry; import com.mapbox.mapboxsdk.LibraryLoader; @@ -68,6 +69,10 @@ final class NativeMapView implements NativeMap { // Flag to indicate destroy was called private boolean destroyed = false; + // Cached to enable lazily set padding. + // Whenever an animation is schedule, this value is cleared and the source of truth becomes the core transform state. + private double[] edgeInsets; + // Holds the pointer to JNI NativeMapView @Keep private long nativePtr = 0; @@ -241,7 +246,8 @@ final class NativeMapView implements NativeMap { if (checkState("setLatLng")) { return; } - nativeSetLatLng(latLng.getLatitude(), latLng.getLongitude(), duration); + nativeSetLatLng(latLng.getLatitude(), latLng.getLongitude(), + getAnimationPaddingAndClearCachedInsets(null), duration); } @Override @@ -374,30 +380,20 @@ final class NativeMapView implements NativeMap { } @Override - public void setContentPadding(float[] padding) { + public void setContentPadding(double[] padding) { if (checkState("setContentPadding")) { return; } - // TopLeftBottomRight - nativeSetContentPadding( - padding[1] / pixelRatio, - padding[0] / pixelRatio, - padding[3] / pixelRatio, - padding[2] / pixelRatio); + this.edgeInsets = padding; } @Override - public float[] getContentPadding() { + public double[] getContentPadding() { if (checkState("getContentPadding")) { - return new float[] {0, 0, 0, 0}; + return new double[] {0, 0, 0, 0}; } - float[] topLeftBottomRight = nativeGetContentPadding(); - return new float[] { - topLeftBottomRight[1] * pixelRatio, - topLeftBottomRight[0] * pixelRatio, - topLeftBottomRight[3] * pixelRatio, - topLeftBottomRight[2] * pixelRatio - }; + // if cached insets are not applied yet, return them, otherwise, get the padding from the camera + return edgeInsets != null ? edgeInsets : getCameraPosition().padding; } @Override @@ -672,29 +668,31 @@ final class NativeMapView implements NativeMap { } @Override - public void jumpTo(@NonNull LatLng center, double zoom, double pitch, double angle) { + public void jumpTo(@NonNull LatLng center, double zoom, double pitch, double angle, double[] padding) { if (checkState("jumpTo")) { return; } - nativeJumpTo(angle, center.getLatitude(), center.getLongitude(), pitch, zoom); + nativeJumpTo(angle, center.getLatitude(), center.getLongitude(), pitch, zoom, + getAnimationPaddingAndClearCachedInsets(padding)); } @Override - public void easeTo(@NonNull LatLng center, double zoom, double angle, double pitch, long duration, + public void easeTo(@NonNull LatLng center, double zoom, double angle, double pitch, double[] padding, long duration, boolean easingInterpolator) { if (checkState("easeTo")) { return; } nativeEaseTo(angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom, - easingInterpolator); + getAnimationPaddingAndClearCachedInsets(padding), easingInterpolator); } @Override - public void flyTo(@NonNull LatLng center, double zoom, double angle, double pitch, long duration) { + public void flyTo(@NonNull LatLng center, double zoom, double angle, double pitch, double[] padding, long duration) { if (checkState("flyTo")) { return; } - nativeFlyTo(angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom); + nativeFlyTo(angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom, + getAnimationPaddingAndClearCachedInsets(padding)); } @Override @@ -703,7 +701,11 @@ final class NativeMapView implements NativeMap { if (checkState("getCameraValues")) { return new CameraPosition.Builder().build(); } - return nativeGetCameraPosition(); + if (edgeInsets != null) { + return new CameraPosition.Builder(nativeGetCameraPosition()).padding(edgeInsets).build(); + } else { + return nativeGetCameraPosition(); + } } @Override @@ -1126,7 +1128,7 @@ final class NativeMapView implements NativeMap { private native void nativeMoveBy(double dx, double dy, long duration); @Keep - private native void nativeSetLatLng(double latitude, double longitude, long duration); + private native void nativeSetLatLng(double latitude, double longitude, double[] padding, long duration); @NonNull @Keep @@ -1176,12 +1178,6 @@ final class NativeMapView implements NativeMap { private native void nativeRotateBy(double sx, double sy, double ex, double ey, long duration); @Keep - private native void nativeSetContentPadding(float top, float left, float bottom, float right); - - @Keep - private native float[] nativeGetContentPadding(); - - @Keep private native void nativeSetBearing(double degrees, long duration); @Keep @@ -1270,16 +1266,17 @@ final class NativeMapView implements NativeMap { private native double nativeGetTopOffsetPixelsForAnnotationSymbol(String symbolName); @Keep - private native void nativeJumpTo(double angle, double latitude, double longitude, double pitch, double zoom); + private native void nativeJumpTo(double angle, double latitude, double longitude, double pitch, double zoom, + double[] padding); @Keep private native void nativeEaseTo(double angle, double latitude, double longitude, - long duration, double pitch, double zoom, + long duration, double pitch, double zoom, double[] padding, boolean easingInterpolator); @Keep private native void nativeFlyTo(double angle, double latitude, double longitude, - long duration, double pitch, double zoom); + long duration, double pitch, double zoom, double[] padding); @NonNull @Keep @@ -1437,6 +1434,20 @@ final class NativeMapView implements NativeMap { return destroyed; } + private double[] getAnimationPaddingAndClearCachedInsets(double[] providedPadding) { + if (providedPadding == null) { + providedPadding = this.edgeInsets; + } + this.edgeInsets = null; + return providedPadding == null ? null : + new double[] { + providedPadding[1] / pixelRatio, + providedPadding[0] / pixelRatio, + providedPadding[3] / pixelRatio, + providedPadding[2] / pixelRatio + }; + } + public interface ViewCallback { @Nullable Bitmap getViewContent(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java index 8ed003b821..76395f9564 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java @@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.maps; import android.graphics.PointF; import android.support.annotation.FloatRange; import android.support.annotation.NonNull; + import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.constants.GeometryConstants; import com.mapbox.mapboxsdk.geometry.LatLng; @@ -24,7 +25,6 @@ public class Projection { private final NativeMap nativeMapView; @NonNull private final MapView mapView; - private int[] contentPadding = new int[] {0, 0, 0, 0}; Projection(@NonNull NativeMap nativeMapView, @NonNull MapView mapView) { this.nativeMapView = nativeMapView; @@ -32,8 +32,7 @@ public class Projection { } void setContentPadding(int[] contentPadding) { - this.contentPadding = contentPadding; - float[] output = new float[contentPadding.length]; + double[] output = new double[contentPadding.length]; for (int i = 0; i < contentPadding.length; i++) { output[i] = contentPadding[i]; } @@ -41,11 +40,15 @@ public class Projection { } int[] getContentPadding() { - return contentPadding; + double[] padding = nativeMapView.getCameraPosition().padding; + return new int[] {(int) padding[0], (int) padding[1], (int) padding[2], (int) padding[3]}; } + /** + * @deprecated unused + */ + @Deprecated public void invalidateContentPadding() { - setContentPadding(contentPadding); } /** @@ -126,10 +129,11 @@ public class Projection { top = 0; bottom = mapView.getHeight(); } else { - left = (float) contentPadding[0]; - right = (float) (mapView.getWidth() - contentPadding[2]); - top = (float) contentPadding[1]; - bottom = (float) (mapView.getHeight() - contentPadding[3]); + int[] contentPadding = getContentPadding(); + left = contentPadding[0]; + right = mapView.getWidth() - contentPadding[2]; + top = contentPadding[1]; + bottom = mapView.getHeight() - contentPadding[3]; } LatLng center = fromScreenLocation(new PointF(left + (right - left) / 2, top + (bottom - top) / 2)); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 1961cf0450..02cd05545d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -108,7 +108,8 @@ public final class Transform implements MapView.OnCameraDidChangeListener { if (isValidCameraPosition(cameraPosition)) { cancelTransitions(); cameraChangeDispatcher.onCameraMoveStarted(OnCameraMoveStartedListener.REASON_API_ANIMATION); - nativeMap.jumpTo(cameraPosition.target, cameraPosition.zoom, cameraPosition.tilt, cameraPosition.bearing); + nativeMap.jumpTo(cameraPosition.target, cameraPosition.zoom, cameraPosition.tilt, cameraPosition.bearing, + cameraPosition.padding); cameraChangeDispatcher.onCameraIdle(); invalidateCameraPosition(); handler.post(new Runnable() { @@ -135,7 +136,7 @@ public final class Transform implements MapView.OnCameraDidChangeListener { } mapView.addOnCameraDidChangeListener(this); nativeMap.easeTo(cameraPosition.target, cameraPosition.zoom, cameraPosition.bearing, cameraPosition.tilt, - durationMs, easingInterpolator); + cameraPosition.padding, durationMs, easingInterpolator); } } @@ -155,7 +156,7 @@ public final class Transform implements MapView.OnCameraDidChangeListener { } mapView.addOnCameraDidChangeListener(this); nativeMap.flyTo(cameraPosition.target, cameraPosition.zoom, cameraPosition.bearing, - cameraPosition.tilt, durationMs); + cameraPosition.tilt, cameraPosition.padding, durationMs); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java index 0c5f3a4be2..6974705fae 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java @@ -1,21 +1,24 @@ package com.mapbox.mapboxsdk.camera; import android.content.res.TypedArray; -import android.os.Parcelable; +import android.os.Parcel; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.utils.MockParcel; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +@RunWith(RobolectricTestRunner.class) public class CameraPositionTest { private static final double DELTA = 1e-15; @@ -23,7 +26,7 @@ public class CameraPositionTest { @Test public void testSanity() { LatLng latLng = new LatLng(1, 2); - CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5); + CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5, new double[] {0, 500, 0, 0}); assertNotNull("cameraPosition should not be null", cameraPosition); } @@ -32,9 +35,10 @@ public class CameraPositionTest { TypedArray typedArray = null; CameraPosition cameraPosition = new CameraPosition.Builder(typedArray).build(); assertEquals("bearing should match", -1, cameraPosition.bearing, DELTA); - assertEquals("latlng should match", null, cameraPosition.target); + assertNull("latlng should be null", cameraPosition.target); assertEquals("tilt should match", -1, cameraPosition.tilt, DELTA); assertEquals("zoom should match", -1, cameraPosition.zoom, DELTA); + assertNull("padding should be null", cameraPosition.padding); } @Test @@ -63,16 +67,16 @@ public class CameraPositionTest { @Test public void testToString() { LatLng latLng = new LatLng(1, 2); - CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5); + CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5, new double[] {0, 500, 0, 0}); assertEquals("toString should match", "Target: LatLng [latitude=1.0, longitude=2.0, altitude=0.0], Zoom:3.0, " - + "Bearing:5.0, Tilt:4.0", cameraPosition.toString()); + + "Bearing:5.0, Tilt:4.0, Padding:[0.0, 500.0, 0.0, 0.0]", cameraPosition.toString()); } @Test public void testHashcode() { LatLng latLng = new LatLng(1, 2); - CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5); - assertEquals("hashCode should match", -1007681505, cameraPosition.hashCode()); + CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5, new double[] {0, 500, 0, 0}); + assertEquals("hashCode should match", -420915327, cameraPosition.hashCode()); } @Test @@ -86,11 +90,12 @@ public class CameraPositionTest { @Test public void testEquals() { LatLng latLng = new LatLng(1, 2); - CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5); - CameraPosition cameraPositionBearing = new CameraPosition(latLng, 3, 4, 9); - CameraPosition cameraPositionTilt = new CameraPosition(latLng, 3, 9, 5); - CameraPosition cameraPositionZoom = new CameraPosition(latLng, 9, 4, 5); - CameraPosition cameraPositionTarget = new CameraPosition(new LatLng(), 3, 4, 5); + CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5, new double[] {0, 500, 0, 0}); + CameraPosition cameraPositionBearing = new CameraPosition(latLng, 3, 4, 9, new double[] {0, 500, 0, 0}); + CameraPosition cameraPositionTilt = new CameraPosition(latLng, 3, 9, 5, new double[] {0, 500, 0, 0}); + CameraPosition cameraPositionZoom = new CameraPosition(latLng, 9, 4, 5, new double[] {0, 500, 0, 0}); + CameraPosition cameraPositionTarget = new CameraPosition(new LatLng(), 3, 4, 5, new double[] {0, 500, 0, 0}); + CameraPosition cameraPositionPadding = new CameraPosition(new LatLng(), 3, 4, 5, new double[] {0, 501, 0, 0}); assertEquals("cameraPosition should match itself", cameraPosition, cameraPosition); assertNotEquals("cameraPosition should not match null", null, cameraPosition); @@ -99,12 +104,17 @@ public class CameraPositionTest { assertNotEquals("cameraPosition should not match for tilt", cameraPositionTilt, cameraPosition); assertNotEquals("cameraPosition should not match for zoom", cameraPositionZoom, cameraPosition); assertNotEquals("cameraPosition should not match for target", cameraPositionTarget, cameraPosition); + assertNotEquals("cameraPosition should not match for padding", cameraPositionPadding, cameraPosition); } @Test public void testParcelable() { - CameraPosition object = new CameraPosition(new LatLng(1, 2), 3, 4, 5); - Parcelable parcelable = MockParcel.obtain(object); - assertEquals("Parcel should match original object", parcelable, object); + CameraPosition cameraPosition1 = new CameraPosition(new LatLng(1, 2), 3, 4, 5, new double[] {0, 500, 0, 0}); + Parcel parcel = Parcel.obtain(); + cameraPosition1.writeToParcel(parcel, 0); + parcel.setDataPosition(0); + + CameraPosition cameraPosition2 = CameraPosition.CREATOR.createFromParcel(parcel); + assertEquals("Parcel should match original object", cameraPosition1, cameraPosition2); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt index 4f6e915d1f..511101ecb2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt +++ b/platform/android/MapboxGLAndroidSDK/src/test/java/com/mapbox/mapboxsdk/maps/TransformTest.kt @@ -25,8 +25,8 @@ class TransformTest { every { nativeMapView.isDestroyed } returns false every { nativeMapView.cameraPosition } returns CameraPosition.DEFAULT every { nativeMapView.cancelTransitions() } answers {} - every { nativeMapView.jumpTo(any(), any(), any(), any()) } answers {} - every { nativeMapView.flyTo(any(), any(), any(), any(), any()) } answers {} + every { nativeMapView.jumpTo(any(), any(), any(), any(), any()) } answers {} + every { nativeMapView.flyTo(any(), any(), any(), any(), any(), any()) } answers {} every { nativeMapView.minZoom = any() } answers {} every { nativeMapView.maxZoom = any() } answers {} } @@ -44,7 +44,7 @@ class TransformTest { val update = CameraUpdateFactory.newCameraPosition(expected) transform.moveCamera(mapboxMap, update, callback) - verify { nativeMapView.jumpTo(target, -1.0, -1.0, -1.0) } + verify { nativeMapView.jumpTo(target, -1.0, -1.0, -1.0, null) } verify { callback.onFinish() } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactoryTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactoryTest.kt index 50b9626edc..f840e970d1 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactoryTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactoryTest.kt @@ -1,11 +1,15 @@ package com.mapbox.mapboxsdk.camera +import android.graphics.PointF +import android.support.test.annotation.UiThreadTest import android.support.test.runner.AndroidJUnit4 import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.geometry.LatLngBounds import com.mapbox.mapboxsdk.testapp.activity.BaseTest import com.mapbox.mapboxsdk.testapp.activity.espresso.DeviceIndependentTestActivity +import org.junit.Assert import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith @@ -17,127 +21,166 @@ class CameraUpdateFactoryTest : BaseTest() { } @Test + @UiThreadTest fun testLatLngBoundsUntiltedUnrotated() { - rule.runOnUiThread { - mapboxMap.cameraPosition = CameraPosition.Builder() - .target(LatLng(60.0, 24.0)) - .bearing(0.0) - .tilt(0.0) - .build() - - val bounds: LatLngBounds = LatLngBounds.Builder() - .include(LatLng(62.0, 26.0)) - .include(LatLng(58.0, 22.0)) - .build() - - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) - - val cameraPosition = mapboxMap.cameraPosition - assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) - assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) - assertEquals("bearing should match:", 0.0, cameraPosition.bearing, 0.1) - assertEquals("zoom should match", 5.5, cameraPosition.zoom, 0.1) - assertEquals("tilt should match:", 0.0, cameraPosition.tilt, 0.1) - } + mapboxMap.cameraPosition = CameraPosition.Builder() + .target(LatLng(60.0, 24.0)) + .bearing(0.0) + .tilt(0.0) + .build() + + val bounds: LatLngBounds = LatLngBounds.Builder() + .include(LatLng(62.0, 26.0)) + .include(LatLng(58.0, 22.0)) + .build() + + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) + + val cameraPosition = mapboxMap.cameraPosition + assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) + assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) + assertEquals("bearing should match:", 0.0, cameraPosition.bearing, 0.1) + assertEquals("zoom should match", 5.5, cameraPosition.zoom, 0.1) + assertEquals("tilt should match:", 0.0, cameraPosition.tilt, 0.1) } @Test + @UiThreadTest fun testLatLngBoundsTilted() { - rule.runOnUiThread { - mapboxMap.cameraPosition = CameraPosition.Builder() - .target(LatLng(60.0, 24.0)) - .bearing(0.0) - .tilt(45.0) - .build() - - val bounds: LatLngBounds = LatLngBounds.Builder() - .include(LatLng(62.0, 26.0)) - .include(LatLng(58.0, 22.0)) - .build() - - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) - - val cameraPosition = mapboxMap.cameraPosition - assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) - assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) - assertEquals("bearing should match:", 0.0, cameraPosition.bearing, 0.1) - assertEquals("zoom should match", 6.0, cameraPosition.zoom, 0.1) - assertEquals("tilt should match:", 45.0, cameraPosition.tilt, 0.1) - } + mapboxMap.cameraPosition = CameraPosition.Builder() + .target(LatLng(60.0, 24.0)) + .bearing(0.0) + .tilt(45.0) + .build() + + val bounds: LatLngBounds = LatLngBounds.Builder() + .include(LatLng(62.0, 26.0)) + .include(LatLng(58.0, 22.0)) + .build() + + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) + + val cameraPosition = mapboxMap.cameraPosition + assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) + assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) + assertEquals("bearing should match:", 0.0, cameraPosition.bearing, 0.1) + assertEquals("zoom should match", 6.0, cameraPosition.zoom, 0.1) + assertEquals("tilt should match:", 45.0, cameraPosition.tilt, 0.1) } @Test + @UiThreadTest fun testLatLngBoundsRotated() { - rule.runOnUiThread { - mapboxMap.cameraPosition = CameraPosition.Builder() - .target(LatLng(60.0, 24.0)) - .bearing(30.0) - .tilt(0.0) - .build() - - val bounds: LatLngBounds = LatLngBounds.Builder() - .include(LatLng(62.0, 26.0)) - .include(LatLng(58.0, 22.0)) - .build() - - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) - - val cameraPosition = mapboxMap.cameraPosition - assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) - assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) - assertEquals("bearing should match:", 30.0, cameraPosition.bearing, 0.1) - assertEquals("zoom should match", 5.3, cameraPosition.zoom, 0.1) - assertEquals("tilt should match:", 0.0, cameraPosition.tilt, 0.1) - } + mapboxMap.cameraPosition = CameraPosition.Builder() + .target(LatLng(60.0, 24.0)) + .bearing(30.0) + .tilt(0.0) + .build() + + val bounds: LatLngBounds = LatLngBounds.Builder() + .include(LatLng(62.0, 26.0)) + .include(LatLng(58.0, 22.0)) + .build() + + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) + + val cameraPosition = mapboxMap.cameraPosition + assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) + assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) + assertEquals("bearing should match:", 30.0, cameraPosition.bearing, 0.1) + assertEquals("zoom should match", 5.3, cameraPosition.zoom, 0.1) + assertEquals("tilt should match:", 0.0, cameraPosition.tilt, 0.1) } @Test + @UiThreadTest fun testLatLngBoundsTiltedRotated() { - rule.runOnUiThread { - mapboxMap.cameraPosition = CameraPosition.Builder() - .target(LatLng(60.0, 24.0)) - .bearing(30.0) - .tilt(45.0) - .build() - - val bounds: LatLngBounds = LatLngBounds.Builder() - .include(LatLng(62.0, 26.0)) - .include(LatLng(58.0, 22.0)) - .build() - - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) - - val cameraPosition = mapboxMap.cameraPosition - assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) - assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) - assertEquals("bearing should match:", 30.0, cameraPosition.bearing, 0.1) - assertEquals("zoom should match", 5.6, cameraPosition.zoom, 0.1) - assertEquals("tilt should match:", 45.0, cameraPosition.tilt, 0.1) - } + mapboxMap.cameraPosition = CameraPosition.Builder() + .target(LatLng(60.0, 24.0)) + .bearing(30.0) + .tilt(45.0) + .build() + + val bounds: LatLngBounds = LatLngBounds.Builder() + .include(LatLng(62.0, 26.0)) + .include(LatLng(58.0, 22.0)) + .build() + + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0)) + + val cameraPosition = mapboxMap.cameraPosition + assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) + assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) + assertEquals("bearing should match:", 30.0, cameraPosition.bearing, 0.1) + assertEquals("zoom should match", 5.6, cameraPosition.zoom, 0.1) + assertEquals("tilt should match:", 45.0, cameraPosition.tilt, 0.1) } @Test + @UiThreadTest fun testLatLngBoundsWithProvidedTiltAndRotation() { - rule.runOnUiThread { - mapboxMap.cameraPosition = CameraPosition.Builder() - .target(LatLng(60.0, 24.0)) - .bearing(0.0) - .tilt(0.0) - .build() - - val bounds: LatLngBounds = LatLngBounds.Builder() - .include(LatLng(62.0, 26.0)) - .include(LatLng(58.0, 22.0)) - .build() - - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 30.0, 40.0, 0)) - - val cameraPosition = mapboxMap.cameraPosition - assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) - assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) - assertEquals("bearing should match:", 30.0, cameraPosition.bearing, 0.1) - assertEquals("zoom should match", 5.6, cameraPosition.zoom, 0.1) - assertEquals("tilt should match:", 40.0, cameraPosition.tilt, 0.1) - } + mapboxMap.cameraPosition = CameraPosition.Builder() + .target(LatLng(60.0, 24.0)) + .bearing(0.0) + .tilt(0.0) + .build() + + val bounds: LatLngBounds = LatLngBounds.Builder() + .include(LatLng(62.0, 26.0)) + .include(LatLng(58.0, 22.0)) + .build() + + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 30.0, 40.0, 0)) + + val cameraPosition = mapboxMap.cameraPosition + assertEquals("latitude should match:", 60.0, cameraPosition.target.latitude, 0.1) + assertEquals("longitude should match:", 24.0, cameraPosition.target.longitude, 0.1) + assertEquals("bearing should match:", 30.0, cameraPosition.bearing, 0.1) + assertEquals("zoom should match", 5.6, cameraPosition.zoom, 0.1) + assertEquals("tilt should match:", 40.0, cameraPosition.tilt, 0.1) + } + + @Test + @UiThreadTest + fun withPadding_cameraInvalidated_paddingPersisting() { + val initialCameraPosition = mapboxMap.cameraPosition + val initialPoint = mapboxMap.projection.toScreenLocation(initialCameraPosition.target) + + val bottomPadding = mapView.height / 4 + val leftPadding = mapView.width / 4 + val padding = doubleArrayOf(leftPadding.toDouble(), 0.0, 0.0, bottomPadding.toDouble()) + mapboxMap.moveCamera(CameraUpdateFactory.paddingTo(leftPadding.toDouble(), 0.0, 0.0, bottomPadding.toDouble())) + + Assert.assertArrayEquals(intArrayOf(leftPadding, 0, 0, bottomPadding), mapboxMap.padding) + + val resultingCameraPosition = mapboxMap.cameraPosition + assertEquals(initialCameraPosition.target, resultingCameraPosition.target) + assertEquals( + PointF(initialPoint.x + leftPadding / 2, initialPoint.y - bottomPadding / 2), + mapboxMap.projection.toScreenLocation(resultingCameraPosition.target) + ) + Assert.assertArrayEquals(padding, resultingCameraPosition.padding, 0.0001) + } + + @Test + @UiThreadTest + fun withLatLngPadding_cameraInvalidated_paddingPersisting() { + val expectedTarget = LatLng(2.0, 2.0) + + val topPadding = mapView.height / 4 + val rightPadding = mapView.width / 4 + val padding = doubleArrayOf(0.0, topPadding.toDouble(), rightPadding.toDouble(), 0.0) + mapboxMap.moveCamera(CameraUpdateFactory.newLatLngPadding(expectedTarget, 0.0, topPadding.toDouble(), rightPadding.toDouble(), 0.0)) + + Assert.assertArrayEquals(intArrayOf(0, topPadding, rightPadding, 0), mapboxMap.padding) + + val resultingCameraPosition = mapboxMap.cameraPosition + assertEquals(expectedTarget.latitude, resultingCameraPosition.target.latitude, 0.1) + assertEquals(expectedTarget.longitude, resultingCameraPosition.target.longitude, 0.1) + + val centerLatLng = mapboxMap.projection.fromScreenLocation(PointF((mapView.width / 2).toFloat(), (mapView.height / 2).toFloat())) + assertTrue(centerLatLng.latitude > resultingCameraPosition.target.latitude) + assertTrue(centerLatLng.longitude > resultingCameraPosition.target.longitude) + Assert.assertArrayEquals(padding, resultingCameraPosition.padding, 0.0001) } }
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt index d5834db553..b13bb6b796 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/NativeMapViewTest.kt @@ -15,6 +15,7 @@ import com.mapbox.mapboxsdk.style.layers.TransitionOptions import com.mapbox.mapboxsdk.testapp.utils.TestConstants import junit.framework.Assert.* import org.junit.After +import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -30,6 +31,7 @@ class NativeMapViewTest : AppCenter() { const val BEARING_TEST = 60.0 const val PITCH_TEST = 40.0 const val ZOOM_TEST = 16.0 + val PADDING_TEST = doubleArrayOf(80.0, 150.0, 0.0, 0.0) const val WIDTH = 500 const val HEIGHT = WIDTH val LATLNG_TEST = LatLng(12.0, 34.0) @@ -88,6 +90,18 @@ class NativeMapViewTest : AppCenter() { @Test @UiThreadTest + fun testLatLngPadding() { + val expected = LATLNG_TEST + nativeMapView.contentPadding = PADDING_TEST + nativeMapView.setLatLng(expected, 0) + val actual = nativeMapView.latLng + assertEquals("Latitude should match", expected.latitude, actual.latitude, DELTA) + assertEquals("Longitude should match", expected.longitude, actual.longitude, DELTA) + Assert.assertArrayEquals(PADDING_TEST, nativeMapView.cameraPosition.padding, DELTA) + } + + @Test + @UiThreadTest fun testLatLngDefault() { val expected = LatLng() val actual = nativeMapView.latLng @@ -145,14 +159,18 @@ class NativeMapViewTest : AppCenter() { .target(LATLNG_TEST) .tilt(PITCH_TEST) .zoom(ZOOM_TEST) + .padding(PADDING_TEST) .build() - nativeMapView.jumpTo(LATLNG_TEST, ZOOM_TEST, PITCH_TEST, BEARING_TEST) + // verify that the lazily set padding is ignored when a value is provided with the camera + nativeMapView.contentPadding = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.jumpTo(LATLNG_TEST, ZOOM_TEST, PITCH_TEST, BEARING_TEST, PADDING_TEST) val actual = nativeMapView.cameraPosition assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, DELTA) assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, DELTA) assertEquals("Bearing should match", expected.bearing, actual.bearing, DELTA) assertEquals("Pitch should match", expected.tilt, actual.tilt, DELTA) assertEquals("Zoom should match", expected.zoom, actual.zoom, DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) } @Test @@ -206,7 +224,7 @@ class NativeMapViewTest : AppCenter() { @Test @UiThreadTest fun testSetContentPadding() { - val expected = floatArrayOf(1.0f, 2.0f, 3.0f, 4.0f) + val expected = doubleArrayOf(1.0, 2.0, 3.0, 4.0) nativeMapView.contentPadding = expected val actual = nativeMapView.contentPadding assertEquals("Left should match", expected[0], actual[0]) @@ -258,14 +276,18 @@ class NativeMapViewTest : AppCenter() { .tilt(30.0) .target(LatLng(12.0, 14.0)) .bearing(20.0) + .padding(PADDING_TEST) .build() - nativeMapView.flyTo(expected.target, expected.zoom, expected.bearing, expected.tilt, 0) + // verify that the lazily set padding is ignored when a value is provided with the camera + nativeMapView.contentPadding = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.flyTo(expected.target, expected.zoom, expected.bearing, expected.tilt, PADDING_TEST, 0) val actual = nativeMapView.cameraPosition assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) } @Test @@ -276,14 +298,18 @@ class NativeMapViewTest : AppCenter() { .tilt(30.0) .target(LatLng(12.0, 14.0)) .bearing(20.0) + .padding(PADDING_TEST) .build() - nativeMapView.easeTo(expected.target, expected.zoom, expected.bearing, expected.tilt, 0, false) + // verify that the lazily set padding is ignored when a value is provided with the camera + nativeMapView.contentPadding = doubleArrayOf(1.0, 2.0, 3.0, 4.0) + nativeMapView.easeTo(expected.target, expected.zoom, expected.bearing, expected.tilt, PADDING_TEST, 0, false) val actual = nativeMapView.cameraPosition assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) assertEquals("Latitude should match", expected.target.latitude, actual.target.latitude, TestConstants.LAT_LNG_DELTA) assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) } @Test @@ -294,8 +320,9 @@ class NativeMapViewTest : AppCenter() { .tilt(0.0) .target(LatLng(0.0, 0.0)) .bearing(0.0) + .padding(PADDING_TEST) .build() - nativeMapView.jumpTo(LatLng(1.0, 2.0), 12.0, 23.0, 1.0) + nativeMapView.jumpTo(LatLng(1.0, 2.0), 12.0, 23.0, 1.0, PADDING_TEST) nativeMapView.resetPosition() val actual = nativeMapView.cameraPosition assertEquals("Bearing should match", expected.bearing, actual.bearing, TestConstants.BEARING_DELTA) @@ -303,6 +330,7 @@ class NativeMapViewTest : AppCenter() { assertEquals("Longitude should match", expected.target.longitude, actual.target.longitude, TestConstants.LAT_LNG_DELTA) assertEquals("Tilt should match", expected.tilt, actual.tilt, TestConstants.TILT_DELTA) assertEquals("Zoom should match", expected.zoom, actual.zoom, TestConstants.ZOOM_DELTA) + Assert.assertArrayEquals(expected.padding, actual.padding, DELTA) } @Test diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java index 625e37798f..69cf1264bf 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java @@ -1,297 +1,11 @@ package com.mapbox.mapboxsdk.testapp.camera; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.IdlingRegistry; -import android.support.test.espresso.idling.CountingIdlingResource; - -import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.activity.BaseTest; -import com.mapbox.mapboxsdk.testapp.activity.espresso.DeviceIndependentTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.TestConstants; - -import org.junit.Test; - -import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; -import static org.junit.Assert.assertEquals; - -public class CameraAnimateTest extends BaseTest { - - private final CountingIdlingResource animationIdlingResource = - new CountingIdlingResource("animation_idling_resource"); - - @Override - protected Class getActivityClass() { - return DeviceIndependentTestActivity.class; - } +public class CameraAnimateTest extends CameraTest { @Override - public void beforeTest() { - super.beforeTest(); - IdlingRegistry.getInstance().register(animationIdlingResource); - } - - @Test - public void testAnimateToCameraPositionTarget() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - LatLng moveTarget = new LatLng(1, 1); - CameraPosition initialPosition = new CameraPosition.Builder().target( - new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Default camera position should match default", cameraPosition, initialPosition); - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(moveTarget), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testAnimateToCameraPositionTargetZoom() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final float moveZoom = 15.5f; - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom), new MapboxMap - .CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testAnimateToCameraPosition() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - final float moveZoom = 15.5f; - final float moveTilt = 45.5f; - final float moveBearing = 12.5f; - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition( - new CameraPosition.Builder() - .target(moveTarget) - .zoom(moveZoom) - .tilt(moveTilt) - .bearing(moveBearing) - .build()), - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testAnimateToBounds() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final LatLng centerBounds = new LatLng(1, 1); - LatLng cornerOne = new LatLng(); - LatLng cornerTwo = new LatLng(2, 2); - final LatLngBounds.Builder builder = new LatLngBounds.Builder(); - builder.include(cornerOne); - builder.include(cornerTwo); - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0), new MapboxMap - .CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); + void executeCameraMovement(CameraUpdate cameraUpdate, MapboxMap.CancelableCallback callback) { + mapboxMap.animateCamera(cameraUpdate, callback); } - - @Test - public void testAnimateToZoomIn() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.zoomIn(), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testAnimateToZoomOut() { - validateTestSetup(); - float zoom = 10.0f; - invoke(mapboxMap, (uiController, mapboxMap) -> { - animationIdlingResource.increment(); - mapboxMap.animateCamera( - CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom), - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - invoke(mapboxMap, ((uiController, mapboxMap1) -> { - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.zoomOut(), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0); - animationIdlingResource.decrement(); - } - }); - })); - - Espresso.onIdle(); - } - - @Test - public void testAnimateToZoomBy() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - final float zoomBy = 2.45f; - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.zoomBy(zoomBy), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testAnimateToZoomTo() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final float zoomTo = 2.45f; - - animationIdlingResource.increment(); - mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(zoomTo), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Override - public void afterTest() { - super.afterTest(); - IdlingRegistry.getInstance().unregister(animationIdlingResource); - } - - private void verifyCameraPosition(MapboxMap mapboxMap, LatLng moveTarget, double moveZoom, double moveBearing, - double moveTilt) { - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); - assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); - assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); - } -} - +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java index ae81dc1302..be3b18ef8b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java @@ -1,294 +1,12 @@ package com.mapbox.mapboxsdk.testapp.camera; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.IdlingRegistry; -import android.support.test.espresso.idling.CountingIdlingResource; - -import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.activity.BaseTest; -import com.mapbox.mapboxsdk.testapp.activity.espresso.DeviceIndependentTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.TestConstants; - -import org.junit.Test; - -import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; -import static org.junit.Assert.assertEquals; - -public class CameraEaseTest extends BaseTest { - private final CountingIdlingResource animationIdlingResource = - new CountingIdlingResource("animation_idling_resource"); - - @Override - protected Class getActivityClass() { - return DeviceIndependentTestActivity.class; - } +public class CameraEaseTest extends CameraTest { @Override - public void beforeTest() { - super.beforeTest(); - IdlingRegistry.getInstance().register(animationIdlingResource); - } - - @Test - public void testEaseToCameraPositionTarget() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - LatLng moveTarget = new LatLng(1, 1); - CameraPosition initialPosition = new CameraPosition.Builder().target( - new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Default camera position should match default", cameraPosition, initialPosition); - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(moveTarget), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToCameraPositionTargetZoom() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final float moveZoom = 15.5f; - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToCameraPosition() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - final float moveZoom = 15.5f; - final float moveTilt = 45.5f; - final float moveBearing = 12.5f; - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition( - new CameraPosition.Builder() - .target(moveTarget) - .zoom(moveZoom) - .tilt(moveTilt) - .bearing(moveBearing) - .build()), - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt); - animationIdlingResource.decrement(); - } - } - ); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToBounds() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final LatLng centerBounds = new LatLng(1, 1); - LatLng cornerOne = new LatLng(); - LatLng cornerTwo = new LatLng(2, 2); - final LatLngBounds.Builder builder = new LatLngBounds.Builder(); - builder.include(cornerOne); - builder.include(cornerTwo); - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0), - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToZoomIn() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.zoomIn(), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToZoomOut() { - float zoom = 10.0f; - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - invoke(mapboxMap, (uiController, mapboxMap) -> { - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.zoomOut(), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToZoomBy() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - final float zoomBy = 2.45f; - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.zoomBy(zoomBy), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testEaseToZoomTo() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final float zoomTo = 2.45f; - - animationIdlingResource.increment(); - mapboxMap.easeCamera(CameraUpdateFactory.zoomTo(zoomTo), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Override - public void afterTest() { - super.afterTest(); - IdlingRegistry.getInstance().unregister(animationIdlingResource); - } - - private void verifyCameraPosition(MapboxMap mapboxMap, LatLng moveTarget, double moveZoom, double moveBearing, - double moveTilt) { - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); - assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); - assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + void executeCameraMovement(CameraUpdate cameraUpdate, MapboxMap.CancelableCallback callback) { + mapboxMap.easeCamera(cameraUpdate, callback); } }
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java index f8aa43d52d..2cd7b6ffe3 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java @@ -1,294 +1,12 @@ package com.mapbox.mapboxsdk.testapp.camera; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.IdlingRegistry; -import android.support.test.espresso.idling.CountingIdlingResource; - -import com.mapbox.mapboxsdk.camera.CameraPosition; -import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.camera.CameraUpdate; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.testapp.activity.BaseTest; -import com.mapbox.mapboxsdk.testapp.activity.espresso.DeviceIndependentTestActivity; -import com.mapbox.mapboxsdk.testapp.utils.TestConstants; - -import org.junit.Test; - -import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; -import static org.junit.Assert.assertEquals; - -public class CameraMoveTest extends BaseTest { - - private final CountingIdlingResource animationIdlingResource = - new CountingIdlingResource("animation_idling_resource"); - - @Override - protected Class getActivityClass() { - return DeviceIndependentTestActivity.class; - } - - @Override - public void beforeTest() { - super.beforeTest(); - IdlingRegistry.getInstance().register(animationIdlingResource); - } - - @Test - public void testMoveToCameraPositionTarget() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - LatLng moveTarget = new LatLng(1, 1); - CameraPosition initialPosition = new CameraPosition.Builder().target( - new LatLng()).zoom(zoom).bearing(0).tilt(0).build(); - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Default camera position should match default", cameraPosition, initialPosition); - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(moveTarget), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToCameraPositionTargetZoom() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final float moveZoom = 15.5f; - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToCameraPosition() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); - final float moveZoom = 15.5f; - final float moveTilt = 45.5f; - final float moveBearing = 12.5f; - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition( - new CameraPosition.Builder() - .target(moveTarget) - .zoom(moveZoom) - .tilt(moveTilt) - .bearing(moveBearing) - .build()), - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToBounds() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final LatLng centerBounds = new LatLng(1, 1); - LatLng cornerOne = new LatLng(); - LatLng cornerTwo = new LatLng(2, 2); - final LatLngBounds.Builder builder = new LatLngBounds.Builder(); - builder.include(cornerOne); - builder.include(cornerTwo); - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 0), - new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToZoomIn() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.zoomIn(), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToZoomOut() { - float zoom = 10.0f; - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - invoke(mapboxMap, (uiController, mapboxMap) -> { - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.zoomOut(), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToZoomBy() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - float zoom = 1.0f; - final float zoomBy = 2.45f; - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.zoomBy(zoomBy), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } - - @Test - public void testMoveToZoomTo() { - validateTestSetup(); - invoke(mapboxMap, (uiController, mapboxMap) -> { - final float zoomTo = 2.45f; - - animationIdlingResource.increment(); - mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(zoomTo), new MapboxMap.CancelableCallback() { - @Override - public void onCancel() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0); - animationIdlingResource.decrement(); - } - - @Override - public void onFinish() { - verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0); - animationIdlingResource.decrement(); - } - }); - }); - - Espresso.onIdle(); - } +public class CameraMoveTest extends CameraTest { @Override - public void afterTest() { - super.afterTest(); - IdlingRegistry.getInstance().unregister(animationIdlingResource); - } - - private void verifyCameraPosition(MapboxMap mapboxMap, LatLng moveTarget, double moveZoom, double moveBearing, - double moveTilt) { - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), - moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), - moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); - assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); - assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); - assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + void executeCameraMovement(CameraUpdate cameraUpdate, MapboxMap.CancelableCallback callback) { + mapboxMap.moveCamera(cameraUpdate, callback); } -} +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraTest.java new file mode 100644 index 0000000000..ebce9aaec5 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraTest.java @@ -0,0 +1,307 @@ +package com.mapbox.mapboxsdk.testapp.camera; + +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.camera.CameraUpdate; +import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.testapp.activity.BaseTest; +import com.mapbox.mapboxsdk.testapp.activity.espresso.DeviceIndependentTestActivity; +import com.mapbox.mapboxsdk.testapp.utils.TestConstants; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static com.mapbox.mapboxsdk.testapp.action.MapboxMapAction.invoke; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public abstract class CameraTest extends BaseTest { + + private CountDownLatch latch; + + @Override + protected Class getActivityClass() { + return DeviceIndependentTestActivity.class; + } + + @Override + public void beforeTest() { + super.beforeTest(); + latch = new CountDownLatch(1); + } + + @Test + public void testToCameraPositionTarget() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + float zoom = 1.0f; + LatLng moveTarget = new LatLng(1, 1); + CameraPosition initialPosition = new CameraPosition.Builder().target( + new LatLng()).zoom(zoom).bearing(0).tilt(0).padding(new double[4]).build(); + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Default camera position should match default", cameraPosition, initialPosition); + + executeCameraMovement(CameraUpdateFactory.newLatLng(moveTarget), new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, moveTarget, zoom, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToCameraPositionTargetZoom() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + final float moveZoom = 15.5f; + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + + executeCameraMovement(CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom), + new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, moveTarget, moveZoom, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToCameraPosition() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003); + final float moveZoom = 15.5f; + final float moveTilt = 45.5f; + final float moveBearing = 12.5f; + final double[] movePadding = new double[] {0, 500, 350, 1}; + + executeCameraMovement(CameraUpdateFactory.newCameraPosition( + new CameraPosition.Builder() + .target(moveTarget) + .zoom(moveZoom) + .tilt(moveTilt) + .bearing(moveBearing) + .padding(movePadding) + .build()), + new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt, movePadding); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, moveTarget, moveZoom, moveBearing, moveTilt, movePadding); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToBounds() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + final LatLng centerBounds = new LatLng(1, 1); + LatLng cornerOne = new LatLng(); + LatLng cornerTwo = new LatLng(2, 2); + final LatLngBounds.Builder builder = new LatLngBounds.Builder(); + builder.include(cornerOne); + builder.include(cornerTwo); + + executeCameraMovement(CameraUpdateFactory.newLatLngBounds(builder.build(), 0), + new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, centerBounds, mapboxMap.getCameraPosition().zoom, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToZoomIn() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + float zoom = 1.0f; + + executeCameraMovement(CameraUpdateFactory.zoomIn(), new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + 1, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToZoomOut() throws InterruptedException { + float zoom = 10.0f; + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + executeCameraMovement(CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom), new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + + latch = new CountDownLatch(1); + + invoke(mapboxMap, (uiController, mapboxMap) -> { + executeCameraMovement(CameraUpdateFactory.zoomOut(), new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom - 1, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToZoomBy() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + float zoom = 1.0f; + final float zoomBy = 2.45f; + + executeCameraMovement(CameraUpdateFactory.zoomBy(zoomBy), new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoom + zoomBy, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + @Test + public void testToZoomTo() throws InterruptedException { + validateTestSetup(); + invoke(mapboxMap, (uiController, mapboxMap) -> { + final float zoomTo = 2.45f; + + executeCameraMovement(CameraUpdateFactory.zoomTo(zoomTo), new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0, new double[4]); + latch.countDown(); + } + + @Override + public void onFinish() { + verifyCameraPosition(mapboxMap, mapboxMap.getCameraPosition().target, zoomTo, 0, 0, new double[4]); + latch.countDown(); + } + }); + }); + + if (!latch.await(10, TimeUnit.SECONDS)) { + Assert.fail("timeout"); + } + } + + abstract void executeCameraMovement(CameraUpdate cameraUpdate, MapboxMap.CancelableCallback callback); + + private void verifyCameraPosition(MapboxMap mapboxMap, LatLng moveTarget, double moveZoom, double moveBearing, + double moveTilt, double[] padding) { + CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(), + moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(), + moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA); + assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA); + assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA); + assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA); + assertArrayEquals("Moved padding should match", cameraPosition.padding, padding, TestConstants.PADDING_DELTA); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java index 09e27d30f2..255d1e1e7d 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java @@ -5,6 +5,7 @@ public class TestConstants { public static final double BEARING_DELTA = 0.1; public static final double TILT_DELTA = 0.3; public static final double ZOOM_DELTA = 0.3; + public static final double PADDING_DELTA = 0.0001; public static final String TEXT_MARKER_TITLE = "Marker"; public static final String TEXT_MARKER_SNIPPET = "Snippet"; diff --git a/platform/android/src/map/camera_position.cpp b/platform/android/src/map/camera_position.cpp index fcbec5639a..03aca79bda 100644 --- a/platform/android/src/map/camera_position.cpp +++ b/platform/android/src/map/camera_position.cpp @@ -4,9 +4,9 @@ namespace mbgl { namespace android { -jni::Local<jni::Object<CameraPosition>> CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOptions options) { +jni::Local<jni::Object<CameraPosition>> CameraPosition::New(jni::JNIEnv &env, mbgl::CameraOptions options, float pixelRatio) { static auto& javaClass = jni::Class<CameraPosition>::Singleton(env); - static auto constructor = javaClass.GetConstructor<jni::Object<LatLng>, double, double, double>(env); + static auto constructor = javaClass.GetConstructor<jni::Object<LatLng>, double, double, double, jni::Array<jni::jdouble>>(env); // wrap LatLng values coming from core auto center = options.center.value(); @@ -25,21 +25,33 @@ jni::Local<jni::Object<CameraPosition>> CameraPosition::New(jni::JNIEnv &env, mb // convert tilt, core ranges from [0 rad, 1,0472 rad], android ranges from 0 to 60 double tilt_degrees = options.pitch.value_or(0); - return javaClass.New(env, constructor, LatLng::New(env, center), options.zoom.value_or(0), tilt_degrees, bearing_degrees); + std::vector<jdouble> paddingVect; + auto insets = options.padding.value_or(EdgeInsets {0, 0, 0, 0}); + auto padding = jni::Array<jni::jdouble>::New(env, 4); + paddingVect.push_back(insets.left() * pixelRatio); + paddingVect.push_back(insets.top() * pixelRatio); + paddingVect.push_back(insets.right() * pixelRatio); + paddingVect.push_back(insets.bottom() * pixelRatio); + padding.SetRegion<std::vector<jni::jdouble>>(env, 0, paddingVect); + + return javaClass.New(env, constructor, LatLng::New(env, center), options.zoom.value_or(0), tilt_degrees, bearing_degrees, padding); } -mbgl::CameraOptions CameraPosition::getCameraOptions(jni::JNIEnv& env, const jni::Object<CameraPosition>& position) { +mbgl::CameraOptions CameraPosition::getCameraOptions(jni::JNIEnv& env, const jni::Object<CameraPosition>& position, float pixelRatio) { static auto& javaClass = jni::Class<CameraPosition>::Singleton(env); static auto bearing = javaClass.GetField<jni::jdouble>(env, "bearing"); static auto target = javaClass.GetField<jni::Object<LatLng>>(env, "target"); static auto tilt = javaClass.GetField<jni::jdouble>(env, "tilt"); static auto zoom = javaClass.GetField<jni::jdouble>(env, "zoom"); + static auto paddingField = javaClass.GetField<jni::Array<jni::jdouble>>(env, "padding"); + static auto padding = position.Get(env, paddingField); auto center = LatLng::getLatLng(env, position.Get(env, target)); return mbgl::CameraOptions { center, - {}, + EdgeInsets {padding.Get(env, 1) * pixelRatio, padding.Get(env, 0) * pixelRatio, + padding.Get(env, 3) * pixelRatio, padding.Get(env, 2) * pixelRatio}, {}, position.Get(env, zoom), position.Get(env, bearing), diff --git a/platform/android/src/map/camera_position.hpp b/platform/android/src/map/camera_position.hpp index 7579f9fed1..b677f04ea0 100644 --- a/platform/android/src/map/camera_position.hpp +++ b/platform/android/src/map/camera_position.hpp @@ -12,9 +12,9 @@ class CameraPosition : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "com/mapbox/mapboxsdk/camera/CameraPosition"; }; - static jni::Local<jni::Object<CameraPosition>> New(jni::JNIEnv&, mbgl::CameraOptions); + static jni::Local<jni::Object<CameraPosition>> New(jni::JNIEnv&, mbgl::CameraOptions, float pixelRatio); - static mbgl::CameraOptions getCameraOptions(jni::JNIEnv&, const jni::Object<CameraPosition>&); + static mbgl::CameraOptions getCameraOptions(jni::JNIEnv&, const jni::Object<CameraPosition>&, float pixelRatio); static void registerNative(jni::JNIEnv&); }; diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index e94ef0153e..8ef757de15 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -336,13 +336,17 @@ void NativeMapView::moveBy(jni::JNIEnv&, jni::jdouble dx, jni::jdouble dy, jni:: map->moveBy({dx, dy}, animationOptions); } -void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble bearing, jni::jdouble latitude, jni::jdouble longitude, jni::jdouble pitch, jni::jdouble zoom) { +void NativeMapView::jumpTo(jni::JNIEnv& env, jni::jdouble bearing, jni::jdouble latitude, jni::jdouble longitude, jni::jdouble pitch, jni::jdouble zoom, const jni::Array<jni::jdouble>& padding) { mbgl::CameraOptions options; if (bearing != -1) { options.bearing = bearing; } options.center = mbgl::LatLng(latitude, longitude); - options.padding = insets; + if (padding) { + assert(padding.Length(env) == 4); + options.padding = mbgl::EdgeInsets{padding.Get(env, 0), padding.Get(env, 1), + padding.Get(env, 2), padding.Get(env, 3)}; + } if (pitch != -1) { options.pitch = pitch; } @@ -353,13 +357,17 @@ void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble bearing, jni::jdouble lati map->jumpTo(options); } -void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble bearing, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom, jni::jboolean easing) { +void NativeMapView::easeTo(jni::JNIEnv& env, jni::jdouble bearing, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom, const jni::Array<jni::jdouble>& padding, jni::jboolean easing) { mbgl::CameraOptions cameraOptions; if (bearing != -1) { cameraOptions.bearing = bearing; } cameraOptions.center = mbgl::LatLng(latitude, longitude); - cameraOptions.padding = insets; + if (padding) { + assert(padding.Length(env) == 4); + cameraOptions.padding = mbgl::EdgeInsets{padding.Get(env, 0), padding.Get(env, 1), + padding.Get(env, 2), padding.Get(env, 3)}; + } if (pitch != -1) { cameraOptions.pitch = pitch; } @@ -377,13 +385,17 @@ void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble bearing, jni::jdouble lati map->easeTo(cameraOptions, animationOptions); } -void NativeMapView::flyTo(jni::JNIEnv&, jni::jdouble bearing, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom) { +void NativeMapView::flyTo(jni::JNIEnv& env, jni::jdouble bearing, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom, const jni::Array<jni::jdouble>& padding) { mbgl::CameraOptions cameraOptions; if (bearing != -1) { cameraOptions.bearing = bearing; } cameraOptions.center = mbgl::LatLng(latitude, longitude); - cameraOptions.padding = insets; + if (padding) { + assert(padding.Length(env) == 4); + cameraOptions.padding = mbgl::EdgeInsets{padding.Get(env, 0), padding.Get(env, 1), + padding.Get(env, 2), padding.Get(env, 3)}; + } if (pitch != -1) { cameraOptions.pitch = pitch; } @@ -397,23 +409,29 @@ void NativeMapView::flyTo(jni::JNIEnv&, jni::jdouble bearing, jni::jdouble latit } jni::Local<jni::Object<LatLng>> NativeMapView::getLatLng(JNIEnv& env) { - return LatLng::New(env, *map->getCameraOptions(insets).center); + return LatLng::New(env, *map->getCameraOptions(mbgl::nullopt).center); } -void NativeMapView::setLatLng(jni::JNIEnv&, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration) { - map->easeTo(mbgl::CameraOptions().withCenter(mbgl::LatLng(latitude, longitude)).withPadding(insets), - mbgl::AnimationOptions{mbgl::Milliseconds(duration)}); +void NativeMapView::setLatLng(jni::JNIEnv& env, jni::jdouble latitude, jni::jdouble longitude, const jni::Array<jni::jdouble>& padding, jni::jlong duration) { + mbgl::CameraOptions cameraOptions; + cameraOptions.center = mbgl::LatLng(latitude, longitude); + if (padding) { + assert(padding.Length(env) == 4); + cameraOptions.padding = mbgl::EdgeInsets{padding.Get(env, 0), padding.Get(env, 1), + padding.Get(env, 2), padding.Get(env, 3)}; + } + map->easeTo(cameraOptions, mbgl::AnimationOptions{mbgl::Milliseconds(duration)}); } jni::Local<jni::Object<CameraPosition>> NativeMapView::getCameraForLatLngBounds(jni::JNIEnv& env, const jni::Object<LatLngBounds>& jBounds, double top, double left, double bottom, double right, double bearing, double tilt) { mbgl::EdgeInsets padding = {top, left, bottom, right}; - return CameraPosition::New(env, map->cameraForLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds), padding, bearing, tilt)); + return CameraPosition::New(env, map->cameraForLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds), padding, bearing, tilt), pixelRatio); } jni::Local<jni::Object<CameraPosition>> NativeMapView::getCameraForGeometry(jni::JNIEnv& env, const jni::Object<geojson::Geometry>& jGeometry, double top, double left, double bottom, double right, double bearing, double tilt) { auto geometry = geojson::Geometry::convert(env, jGeometry); mbgl::EdgeInsets padding = {top, left, bottom, right}; - return CameraPosition::New(env, map->cameraForGeometry(geometry, padding, bearing, tilt)); + return CameraPosition::New(env, map->cameraForGeometry(geometry, padding, bearing, tilt), pixelRatio); } void NativeMapView::setReachability(jni::JNIEnv&, jni::jboolean reachable) { @@ -514,21 +532,6 @@ void NativeMapView::setVisibleCoordinateBounds(JNIEnv& env, const jni::Array<jni map->easeTo(cameraOptions, animationOptions); } -void NativeMapView::setContentPadding(JNIEnv&, float top, float left, float bottom, float right) { - insets = {top, left, bottom, right}; -} - -jni::Local<jni::Array<jni::jfloat>> NativeMapView::getContentPadding(JNIEnv& env) { - auto result = jni::Array<jni::jfloat>::New(env, 4); - std::vector<jfloat> vect; - vect.push_back(insets.top()); - vect.push_back(insets.left()); - vect.push_back(insets.bottom()); - vect.push_back(insets.right()); - result.SetRegion<std::vector<jni::jfloat>>(env, 0, vect); - return result; -} - void NativeMapView::scheduleSnapshot(jni::JNIEnv&) { mapRenderer.requestSnapshot([&](PremultipliedImage image) { auto _env = android::AttachEnv(); @@ -546,7 +549,7 @@ void NativeMapView::scheduleSnapshot(jni::JNIEnv&) { } jni::Local<jni::Object<CameraPosition>> NativeMapView::getCameraPosition(jni::JNIEnv& env) { - return CameraPosition::New(env, map->getCameraOptions(insets)); + return CameraPosition::New(env, map->getCameraOptions(mbgl::nullopt), pixelRatio); } void NativeMapView::updateMarker(jni::JNIEnv& env, jni::jlong markerId, jni::jdouble lat, jni::jdouble lon, const jni::String& jid) { @@ -1096,8 +1099,6 @@ void NativeMapView::registerNative(jni::JNIEnv& env) { METHOD(&NativeMapView::getBearing, "nativeGetBearing"), METHOD(&NativeMapView::resetNorth, "nativeResetNorth"), METHOD(&NativeMapView::setVisibleCoordinateBounds, "nativeSetVisibleCoordinateBounds"), - METHOD(&NativeMapView::setContentPadding, "nativeSetContentPadding"), - METHOD(&NativeMapView::getContentPadding, "nativeGetContentPadding"), METHOD(&NativeMapView::scheduleSnapshot, "nativeTakeSnapshot"), METHOD(&NativeMapView::getCameraPosition, "nativeGetCameraPosition"), METHOD(&NativeMapView::updateMarker, "nativeUpdateMarker"), diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index 10b2af0669..26567a003c 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -91,15 +91,15 @@ public: void moveBy(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jlong); - void jumpTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble); + void jumpTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble, const jni::Array<jni::jdouble>&); - void easeTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong, jni::jdouble, jni::jdouble, jni::jboolean); + void easeTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong, jni::jdouble, jni::jdouble, const jni::Array<jni::jdouble>&, jni::jboolean); - void flyTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong, jni::jdouble, jni::jdouble); + void flyTo(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong, jni::jdouble, jni::jdouble, const jni::Array<jni::jdouble>&); jni::Local<jni::Object<LatLng>> getLatLng(JNIEnv&); - void setLatLng(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jlong); + void setLatLng(jni::JNIEnv&, jni::jdouble, jni::jdouble, const jni::Array<jni::jdouble>&, jni::jlong); jni::Local<jni::Object<CameraPosition>> getCameraForLatLngBounds(jni::JNIEnv&, const jni::Object<mbgl::android::LatLngBounds>&, double top, double left, double bottom, double right, double bearing, double tilt); @@ -139,10 +139,6 @@ public: void setVisibleCoordinateBounds(JNIEnv&, const jni::Array<jni::Object<LatLng>>&, const jni::Object<RectF>&, jni::jdouble, jni::jlong); - void setContentPadding(JNIEnv&, float, float, float, float); - - jni::Local<jni::Array<jni::jfloat>> getContentPadding(JNIEnv&); - void scheduleSnapshot(jni::JNIEnv&); jni::Local<jni::Object<CameraPosition>> getCameraPosition(jni::JNIEnv&); @@ -259,7 +255,6 @@ private: // Ensure these are initialised last std::unique_ptr<mbgl::Map> map; - mbgl::EdgeInsets insets; }; } // namespace android diff --git a/platform/android/src/snapshotter/map_snapshotter.cpp b/platform/android/src/snapshotter/map_snapshotter.cpp index 2d37710605..0b38269ada 100644 --- a/platform/android/src/snapshotter/map_snapshotter.cpp +++ b/platform/android/src/snapshotter/map_snapshotter.cpp @@ -38,7 +38,7 @@ MapSnapshotter::MapSnapshotter(jni::JNIEnv& _env, optional<mbgl::CameraOptions> cameraOptions; if (position) { - cameraOptions = CameraPosition::getCameraOptions(_env, position); + cameraOptions = CameraPosition::getCameraOptions(_env, position, pixelRatio); } optional<mbgl::LatLngBounds> bounds; @@ -124,7 +124,7 @@ void MapSnapshotter::setSize(JNIEnv&, jni::jint width, jni::jint height) { } void MapSnapshotter::setCameraPosition(JNIEnv& env, const jni::Object<CameraPosition>& position) { - auto options = CameraPosition::getCameraOptions(env, position); + auto options = CameraPosition::getCameraOptions(env, position, pixelRatio); snapshotter->setCameraOptions(options); } |