Cherry pick release v4.2.0 (#6944)
* [android] - MyLocationView should facing above when location and compass bearing tracking are enabled. (#6829) * [android] - use current animated rotation value for calculating animated marker rotation difference (#6826) fix unit tests, input limiting is not handled by animateRotationBy instead of MarkerView. Changed test to validate if method was called with correct value. * [android] - only calculated offset margins for InfoWindow if View is found in current viewport, added example to the test app to test for regressions (#6877) * upgraded okhttp dependency to latest version (#6880) * Cancelable callback invocation (#6891) * [android] - allow onCancel to be invoked from camera cancel callbacks * set to null after finish * [android] - using bearing clockwise versus counterclockwise (#6917) * [android] - using bearing clockwise versus counterclockwise * fixup brackets * [android] - convert bearing values from core to Android SDK equivalent.
This commit is contained in:
@@ -136,33 +136,38 @@ public class InfoWindow {
|
||||
boolean outOfBoundsLeft = false;
|
||||
boolean outOfBoundsRight = false;
|
||||
|
||||
// if out of bounds right
|
||||
if (rightSideInfowWindow > mapRight) {
|
||||
outOfBoundsRight = true;
|
||||
x -= rightSideInfowWindow - mapRight;
|
||||
tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset;
|
||||
rightSideInfowWindow = x + view.getMeasuredWidth();
|
||||
}
|
||||
// only optimise margins if view is inside current viewport
|
||||
if (mCoordinates.x >= 0 && mCoordinates.x <= mapView.getWidth()
|
||||
&& mCoordinates.y >= 0 && mCoordinates.y <= mapView.getHeight()) {
|
||||
|
||||
// fit screen left
|
||||
if (leftSideInfoWindow < mapLeft) {
|
||||
outOfBoundsLeft = true;
|
||||
x += mapLeft - leftSideInfoWindow;
|
||||
tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset;
|
||||
leftSideInfoWindow = x;
|
||||
}
|
||||
// if out of bounds right
|
||||
if (rightSideInfowWindow > mapRight) {
|
||||
outOfBoundsRight = true;
|
||||
x -= rightSideInfowWindow - mapRight;
|
||||
tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset;
|
||||
rightSideInfowWindow = x + view.getMeasuredWidth();
|
||||
}
|
||||
|
||||
// Add margin right
|
||||
if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) {
|
||||
x -= marginHorizontal - (mapRight - rightSideInfowWindow);
|
||||
tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset;
|
||||
leftSideInfoWindow = x;
|
||||
}
|
||||
// fit screen left
|
||||
if (leftSideInfoWindow < mapLeft) {
|
||||
outOfBoundsLeft = true;
|
||||
x += mapLeft - leftSideInfoWindow;
|
||||
tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset;
|
||||
leftSideInfoWindow = x;
|
||||
}
|
||||
|
||||
// Add margin left
|
||||
if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) {
|
||||
x += marginHorizontal - (leftSideInfoWindow - mapLeft);
|
||||
tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset;
|
||||
// Add margin right
|
||||
if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) {
|
||||
x -= marginHorizontal - (mapRight - rightSideInfowWindow);
|
||||
tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset;
|
||||
leftSideInfoWindow = x;
|
||||
}
|
||||
|
||||
// Add margin left
|
||||
if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) {
|
||||
x += marginHorizontal - (leftSideInfoWindow - mapLeft);
|
||||
tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust tipView
|
||||
|
||||
@@ -265,17 +265,9 @@ public class MarkerView extends Marker {
|
||||
newRotation += 360;
|
||||
}
|
||||
|
||||
// calculate new direction
|
||||
float diff = newRotation - this.rotation;
|
||||
if (diff > 180.0f) {
|
||||
diff -= 360.0f;
|
||||
} else if (diff < -180.0f) {
|
||||
diff += 360.f;
|
||||
}
|
||||
|
||||
this.rotation = newRotation;
|
||||
if (markerViewManager != null) {
|
||||
markerViewManager.animateRotationBy(this, diff);
|
||||
markerViewManager.animateRotationBy(this, newRotation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,12 +74,20 @@ public class MarkerViewManager {
|
||||
* Animate a MarkerView with a given rotation.
|
||||
*
|
||||
* @param marker the MarkerView to rotate by
|
||||
* @param rotation the rotation by value
|
||||
* @param rotation the rotation by value, limited to 0 - 360 degrees
|
||||
*/
|
||||
public void animateRotationBy(@NonNull MarkerView marker, float rotation) {
|
||||
View convertView = markerViewMap.get(marker);
|
||||
if (convertView != null) {
|
||||
AnimatorUtils.rotateBy(convertView, rotation);
|
||||
convertView.animate().cancel();
|
||||
// calculate new direction
|
||||
float diff = rotation - convertView.getRotation();
|
||||
if (diff > 180.0f) {
|
||||
diff -= 360.0f;
|
||||
} else if (diff < -180.0f) {
|
||||
diff += 360.f;
|
||||
}
|
||||
AnimatorUtils.rotateBy(convertView, diff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.utils.MathUtils;
|
||||
|
||||
import static com.mapbox.mapboxsdk.utils.MathUtils.convertNativeBearing;
|
||||
|
||||
/**
|
||||
* Resembles the position, angle, zoom and tilt of the user's viewpoint.
|
||||
*/
|
||||
@@ -202,7 +204,7 @@ public final class CameraPosition implements Parcelable {
|
||||
super();
|
||||
if (nativeCameraValues != null && nativeCameraValues.length == 5) {
|
||||
target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
|
||||
bearing(nativeCameraValues[2]);
|
||||
bearing(convertNativeBearing(nativeCameraValues[2]));
|
||||
tilt(nativeCameraValues[3]);
|
||||
zoom((float) nativeCameraValues[4]);
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import static com.mapbox.mapboxsdk.utils.MathUtils.convertNativeBearing;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A {@code MapView} provides an embeddable map interface.
|
||||
@@ -151,6 +153,7 @@ public class MapView extends FrameLayout {
|
||||
private boolean styleWasSet = false;
|
||||
|
||||
private List<OnMapReadyCallback> onMapReadyCallbackList;
|
||||
private MapboxMap.CancelableCallback cameraCancelableCallback;
|
||||
private SnapshotRequest snapshotRequest;
|
||||
|
||||
private boolean onStartCalled;
|
||||
@@ -708,16 +711,7 @@ public class MapView extends FrameLayout {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double direction = -nativeMapView.getBearing();
|
||||
|
||||
while (direction > 360) {
|
||||
direction -= 360;
|
||||
}
|
||||
while (direction < 0) {
|
||||
direction += 360;
|
||||
}
|
||||
|
||||
return direction;
|
||||
return convertNativeBearing(nativeMapView.getBearing());
|
||||
}
|
||||
|
||||
void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction) {
|
||||
@@ -732,7 +726,7 @@ public class MapView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
long duration = animated ? MapboxConstants.ANIMATION_DURATION : 0;
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
// Out of range directions are normalised in setBearing
|
||||
nativeMapView.setBearing(-direction, duration);
|
||||
}
|
||||
@@ -742,7 +736,7 @@ public class MapView extends FrameLayout {
|
||||
return;
|
||||
}
|
||||
myLocationView.setBearing(0);
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
nativeMapView.resetNorth();
|
||||
}
|
||||
|
||||
@@ -812,7 +806,7 @@ public class MapView extends FrameLayout {
|
||||
|
||||
private void zoom(boolean zoomIn, float x, float y) {
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
if (zoomIn) {
|
||||
nativeMapView.scaleBy(2.0, x / screenDensity, y / screenDensity, MapboxConstants.ANIMATION_DURATION);
|
||||
@@ -1066,11 +1060,19 @@ public class MapView extends FrameLayout {
|
||||
// Mapbox Core GL Camera
|
||||
//
|
||||
|
||||
private void cancelTransitions(){
|
||||
if (cameraCancelableCallback != null) {
|
||||
cameraCancelableCallback.onCancel();
|
||||
cameraCancelableCallback = null;
|
||||
}
|
||||
nativeMapView.cancelTransitions();
|
||||
}
|
||||
|
||||
void jumpTo(double bearing, LatLng center, double pitch, double zoom) {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
nativeMapView.jumpTo(bearing, center, pitch, zoom);
|
||||
}
|
||||
|
||||
@@ -1078,16 +1080,17 @@ public class MapView extends FrameLayout {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Register callbacks early enough
|
||||
if (cancelableCallback != null) {
|
||||
cameraCancelableCallback = cancelableCallback;
|
||||
addOnMapChangedListener(new OnMapChangedListener() {
|
||||
@Override
|
||||
public void onMapChanged(@MapChange int change) {
|
||||
if (change == REGION_DID_CHANGE_ANIMATED) {
|
||||
cancelableCallback.onFinish();
|
||||
|
||||
if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) {
|
||||
cameraCancelableCallback.onFinish();
|
||||
cameraCancelableCallback = null;
|
||||
// Clean up after self
|
||||
removeOnMapChangedListener(this);
|
||||
}
|
||||
@@ -1102,16 +1105,17 @@ public class MapView extends FrameLayout {
|
||||
if (destroyed) {
|
||||
return;
|
||||
}
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Register callbacks early enough
|
||||
if (cancelableCallback != null) {
|
||||
cameraCancelableCallback = cancelableCallback;
|
||||
addOnMapChangedListener(new OnMapChangedListener() {
|
||||
@Override
|
||||
public void onMapChanged(@MapChange int change) {
|
||||
if (change == REGION_DID_CHANGE_ANIMATED) {
|
||||
if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) {
|
||||
cancelableCallback.onFinish();
|
||||
|
||||
cameraCancelableCallback = null;
|
||||
// Clean up after self
|
||||
removeOnMapChangedListener(this);
|
||||
}
|
||||
@@ -1545,7 +1549,7 @@ public class MapView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1647,7 +1651,7 @@ public class MapView extends FrameLayout {
|
||||
double duration = speed / (deceleration * ease);
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
nativeMapView.moveBy(velocityX * duration / 2.0 / screenDensity, velocityY * duration / 2.0 / screenDensity, (long) (duration * 1000.0f));
|
||||
|
||||
@@ -1679,7 +1683,7 @@ public class MapView extends FrameLayout {
|
||||
// reset tracking if needed
|
||||
resetTrackingModesIfRequired(true, false);
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Scroll the map
|
||||
nativeMapView.moveBy(-distanceX / screenDensity, -distanceY / screenDensity);
|
||||
@@ -1750,7 +1754,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Gesture is a quickzoom if there aren't two fingers
|
||||
quickZoom = !twoTap;
|
||||
@@ -1831,7 +1835,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// rotation constitutes translation of anything except the center of
|
||||
// rotation, so cancel both location and bearing tracking if required
|
||||
@@ -1907,7 +1911,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Get tilt value (scale and clamp)
|
||||
double pitch = getTilt();
|
||||
@@ -1974,7 +1978,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Move left
|
||||
nativeMapView.moveBy(scrollDist / screenDensity, 0.0 / screenDensity);
|
||||
@@ -1986,7 +1990,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Move right
|
||||
nativeMapView.moveBy(-scrollDist / screenDensity, 0.0 / screenDensity);
|
||||
@@ -1998,7 +2002,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Move up
|
||||
nativeMapView.moveBy(0.0 / screenDensity, scrollDist / screenDensity);
|
||||
@@ -2010,7 +2014,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Move down
|
||||
nativeMapView.moveBy(0.0 / screenDensity, -scrollDist / screenDensity);
|
||||
@@ -2090,7 +2094,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Scroll the map
|
||||
nativeMapView.moveBy(-10.0 * event.getX() / screenDensity, -10.0 * event.getY() / screenDensity);
|
||||
@@ -2186,7 +2190,7 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
nativeMapView.cancelTransitions();
|
||||
cancelTransitions();
|
||||
|
||||
// Get the vertical scroll amount, one click = 1
|
||||
float scrollDist = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
|
||||
|
||||
@@ -541,8 +541,6 @@ public class MyLocationView extends View {
|
||||
float[] matrix = new float[9];
|
||||
float[] orientation = new float[3];
|
||||
|
||||
private int currentDegree = 0;
|
||||
|
||||
// Compass data
|
||||
private long compassUpdateNextTimestamp = 0;
|
||||
|
||||
@@ -575,22 +573,22 @@ public class MyLocationView extends View {
|
||||
SensorManager.getOrientation(matrix, orientation);
|
||||
|
||||
float magneticHeading = (float) Math.toDegrees(SensorManager.getOrientation(matrix, orientation)[0]);
|
||||
currentDegree = (int) (magneticHeading);
|
||||
|
||||
// Change the user location view orientation to reflect the device orientation
|
||||
setCompass(currentDegree);
|
||||
|
||||
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
|
||||
rotateCamera();
|
||||
// Change the user location view orientation to reflect the device orientation
|
||||
rotateCamera(magneticHeading);
|
||||
setCompass(0);
|
||||
} else {
|
||||
// Change compass direction
|
||||
setCompass(magneticHeading);
|
||||
}
|
||||
|
||||
compassUpdateNextTimestamp = currentTime + COMPASS_UPDATE_RATE_MS;
|
||||
}
|
||||
}
|
||||
|
||||
private void rotateCamera() {
|
||||
private void rotateCamera(float rotation) {
|
||||
CameraPosition.Builder builder = new CameraPosition.Builder();
|
||||
builder.bearing(currentDegree);
|
||||
builder.bearing(rotation);
|
||||
mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), COMPASS_UPDATE_RATE_MS, false /*linear interpolator*/, false /*do not disable tracking*/, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,4 +43,22 @@ public class MathUtils {
|
||||
|
||||
return secondMod + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert bearing from core to match Android SDK value.
|
||||
*
|
||||
* @param nativeBearing bearing value coming from core
|
||||
* @return bearing in degrees starting from 0 rotating clockwise
|
||||
*/
|
||||
public static double convertNativeBearing(double nativeBearing) {
|
||||
double direction = -nativeBearing;
|
||||
|
||||
while (direction > 360) {
|
||||
direction -= 360;
|
||||
}
|
||||
while (direction < 0) {
|
||||
direction += 360;
|
||||
}
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user