diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 8fe9568eaa6..688453743a7 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -629,46 +629,13 @@ void setTilt(Double pitch) { // Direction // - double getDirection() { - if (mDestroyed) { - return 0; - } - - double direction = -mNativeMapView.getBearing(); - - while (direction > 360) { - direction -= 360; - } - while (direction < 0) { - direction += 360; - } - - return direction; - } - - void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction) { - if (mDestroyed) { - return; - } - setDirection(direction, false); - } - - void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction, boolean animated) { - if (mDestroyed) { - return; - } - long duration = animated ? MapboxConstants.ANIMATION_DURATION : 0; - mNativeMapView.cancelTransitions(); - // Out of range directions are normalised in setBearing - mNativeMapView.setBearing(-direction, duration); - } - void resetNorth() { if (mDestroyed) { return; } mNativeMapView.cancelTransitions(); mNativeMapView.resetNorth(); + mMyLocationView.setBearing(0); } // @@ -754,7 +721,7 @@ private void zoom(boolean zoomIn, float x, float y) { } // work around to invalidate camera position - postDelayed(new ZoomInvalidator(mMapboxMap), MapboxConstants.ANIMATION_DURATION); + postDelayed(new ZoomInvalidator(mMapboxMap, mMyLocationView), MapboxConstants.ANIMATION_DURATION); } // @@ -1212,9 +1179,10 @@ void jumpTo(double bearing, LatLng center, double pitch, double zoom) { } mNativeMapView.cancelTransitions(); mNativeMapView.jumpTo(bearing, center, pitch, zoom); + mMyLocationView.setCameraPositionAttributes(pitch, bearing); } - void easeTo(double bearing, LatLng center, long duration, double pitch, double zoom, boolean easingInterpolator, @Nullable final MapboxMap.CancelableCallback cancelableCallback) { + void easeTo(final double bearing, LatLng center, long duration, final double pitch, double zoom, boolean easingInterpolator, @Nullable final MapboxMap.CancelableCallback cancelableCallback) { if (mDestroyed) { return; } @@ -1228,6 +1196,8 @@ public void onMapChanged(@MapChange int change) { if (change == REGION_DID_CHANGE_ANIMATED) { cancelableCallback.onFinish(); + mMyLocationView.setCameraPositionAttributes(pitch, bearing); + // Clean up after self removeOnMapChangedListener(this); } @@ -1238,7 +1208,7 @@ public void onMapChanged(@MapChange int change) { mNativeMapView.easeTo(bearing, center, duration, pitch, zoom, easingInterpolator); } - void flyTo(double bearing, LatLng center, long duration, double pitch, double zoom, @Nullable final MapboxMap.CancelableCallback cancelableCallback) { + void flyTo(final double bearing, LatLng center, long duration, final double pitch, double zoom, @Nullable final MapboxMap.CancelableCallback cancelableCallback) { if (mDestroyed) { return; } @@ -1252,6 +1222,8 @@ public void onMapChanged(@MapChange int change) { if (change == REGION_DID_CHANGE_ANIMATED) { cancelableCallback.onFinish(); + mMyLocationView.setCameraPositionAttributes(pitch, bearing); + // Clean up after self removeOnMapChangedListener(this); } @@ -1350,10 +1322,6 @@ protected void onSizeChanged(int width, int height, int oldw, int oldh) { private class SurfaceTextureListener implements TextureView.SurfaceTextureListener { private Surface mSurface; - private View mViewHolder; - - private static final int VIEW_MARKERS_POOL_SIZE = 20; - // Called when the native surface texture has been created // Must do all EGL/GL ES initialization here @@ -1396,12 +1364,12 @@ public void onSurfaceTextureUpdated(SurfaceTexture surface) { return; } - mCompassView.update(getDirection()); + mCompassView.update(mMapboxMap.getCameraPosition().bearing); mMyLocationView.update(); try { mMapboxMap.getMarkerViewManager().update(); - }catch (NullPointerException e){ + } catch (NullPointerException e) { } for (InfoWindow infoWindow : mMapboxMap.getInfoWindows()) { @@ -1410,15 +1378,6 @@ public void onSurfaceTextureUpdated(SurfaceTexture surface) { } } - // Used by UserLocationView - void update() { - if (mDestroyed) { - return; - } - - mNativeMapView.update(); - } - CameraPosition invalidateCameraPosition() { if (mDestroyed) { return new CameraPosition.Builder().build(); @@ -1430,7 +1389,25 @@ CameraPosition invalidateCameraPosition() { if (mDestroyed) { return 0; } - return mNativeMapView.getBearing(); + + double bearing = -mNativeMapView.getBearing(); + + while (bearing > 360) { + bearing -= 360; + } + while (bearing < 0) { + bearing += 360; + } + + return bearing; + } + + void setBearing(double bearing, float centerX, float centerY) { + if (mDestroyed) { + return; + } + mNativeMapView.setBearing(bearing, centerX, centerY); + mMyLocationView.setBearing(bearing); } void setBearing(float bearing) { @@ -1438,6 +1415,7 @@ void setBearing(float bearing) { return; } mNativeMapView.setBearing(bearing); + mMyLocationView.setBearing(bearing); } void setBearing(float bearing, long duration) { @@ -1445,6 +1423,7 @@ void setBearing(float bearing, long duration) { return; } mNativeMapView.setBearing(bearing, duration); + mMyLocationView.setBearing(bearing); } // @@ -1826,6 +1805,10 @@ public void onScaleEnd(ScaleGestureDetector detector) { mBeginTime = 0; mScaleFactor = 1.0f; mZoomStarted = false; + + if (mMyLocationView.isEnabled()) { + mMyLocationView.invalidateZoom(); + } } // Called each time a finger moves @@ -1863,7 +1846,7 @@ public boolean onScale(ScaleGestureDetector detector) { // Scale the map if (mFocalPoint != null) { - // arround user provided focal point + // around user provided focal point mNativeMapView.scaleBy(detector.getScaleFactor(), mFocalPoint.x / mScreenDensity, mFocalPoint.y / mScreenDensity); } else if (mQuickZoom) { // around center map @@ -1944,10 +1927,10 @@ public boolean onRotate(RotateGestureDetector detector) { // Rotate the map if (mFocalPoint != null) { // User provided focal point - mNativeMapView.setBearing(bearing, mFocalPoint.x / mScreenDensity, mFocalPoint.y / mScreenDensity); + setBearing(bearing, mFocalPoint.x / mScreenDensity, mFocalPoint.y / mScreenDensity); } else { // around gesture - mNativeMapView.setBearing(bearing, + setBearing(bearing, detector.getFocusX() / mScreenDensity, detector.getFocusY() / mScreenDensity); } @@ -2726,15 +2709,20 @@ public void onItemClick(AdapterView parent, View view, int position, long id) private static class ZoomInvalidator implements Runnable { private MapboxMap mapboxMap; + private MyLocationView myLocationView; - public ZoomInvalidator(MapboxMap mapboxMap) { + public ZoomInvalidator(MapboxMap mapboxMap, MyLocationView myLocationView) { this.mapboxMap = mapboxMap; + this.myLocationView = myLocationView; } @Override public void run() { // invalidate camera position mapboxMap.getCameraPosition(); + if(myLocationView.isEnabled()) { + myLocationView.invalidateZoom(); + } } } 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 b0df57fe1d1..669b8906384 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 @@ -1629,7 +1629,7 @@ void setProjection(Projection projection) { * Triggers an invalidation of the map view. */ public void invalidate() { - mMapView.update(); + mMapView.invalidate(); } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java index 30492bc4212..e23ed15400d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java @@ -215,7 +215,7 @@ private void validateGesturesForLocationTrackingMode() { private void validateGesturesForBearingTrackingMode() { int myBearingTrackingMode = getMyBearingTrackingMode(); if (!dismissBearingTrackingOnGesture) { - if (myBearingTrackingMode == MyBearingTracking.NONE) { + if (myBearingTrackingMode == MyBearingTracking.NONE || myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) { uiSettings.setRotateGesturesEnabled(true); } else { uiSettings.setRotateGesturesEnabled(false); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index 49141d3389b..1f4b2ddbfb1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -1,6 +1,6 @@ package com.mapbox.mapboxsdk.maps.widgets; -import android.animation.ObjectAnimator; +import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Camera; @@ -56,6 +56,8 @@ public class MyLocationView extends View { private LatLng interpolatedLocation; private LatLng previousLocation; private long locationUpdateTimestamp; + private float metersPerPixelAtLatitude; + private static final long MAX_ANIMATION_TIME = 5000; private float gpsDirection; private float previousDirection; @@ -93,6 +95,8 @@ public void onAnimationUpdate(ValueAnimator animation) { private Matrix matrix; private Camera camera; private PointF screenLocation; + + private float direction; private float tilt; @MyLocationTracking.Mode @@ -251,9 +255,7 @@ protected void onDraw(Canvas canvas) { } final PointF pointF = screenLocation; - - float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude()); - float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel / 2; + float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixelAtLatitude / 2; float maxRadius = getWidth() / 2; accuracyPixels = accuracyPixels <= maxRadius ? accuracyPixels : maxRadius; @@ -262,14 +264,14 @@ protected void onDraw(Canvas canvas) { // apply tilt to camera camera.save(); - camera.rotate(tilt, 0, 0); + camera.rotate(tilt, 0, direction); // map camera matrix on our matrix camera.getMatrix(matrix); - // + // apply rotation if (myBearingTrackingMode != MyBearingTracking.NONE && directionAnimator != null) { - matrix.postRotate((Float) directionAnimator.getAnimatedValue()); + matrix.preRotate((Float) directionAnimator.getAnimatedValue()); } // put matrix at location of MyLocationView @@ -303,8 +305,21 @@ public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) { this.tilt = (float) tilt; } - void updateOnNextFrame() { - mapboxMap.invalidate(); + public void setBearing(double bearing) { + this.direction = (float) bearing; + } + + public void setCameraPositionAttributes(@FloatRange(from = 0, to = 60.0f) double tilt, double bearing) { + this.tilt = (float) tilt; + this.direction = (float) bearing; + invalidateZoom(); + } + + public void invalidateZoom() { + if (location != null) { + metersPerPixelAtLatitude = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude()); + invalidate(); + } } public void onPause() { @@ -350,8 +365,8 @@ protected Parcelable onSaveInstanceState() { } @Override - public void onRestoreInstanceState(Parcelable state){ - if (state instanceof Bundle){ + public void onRestoreInstanceState(Parcelable state) { + if (state instanceof Bundle) { Bundle bundle = (Bundle) state; tilt = bundle.getFloat("tilt"); state = bundle.getParcelable("superState"); @@ -451,7 +466,7 @@ private void setCompass(float bearing) { previousDirection = newDir; directionAnimator = ValueAnimator.ofFloat(oldDir, newDir); - directionAnimator.setDuration(375); + directionAnimator.setDuration(575); directionAnimator.addUpdateListener(invalidateSelfOnUpdateListener); directionAnimator.start(); } @@ -506,7 +521,7 @@ private class CompassListener implements SensorEventListener { private float[] mI = new float[16]; // Controls the sensor updateLatLng rate in milliseconds - private static final int UPDATE_RATE_MS = 500; + private static final int UPDATE_RATE_MS = 1000; // Compass data private long mCompassUpdateNextTimestamp = 0; @@ -569,7 +584,7 @@ public void onAccuracyChanged(Sensor sensor, int accuracy) { } } - private class MarkerCoordinateAnimatorListener implements ValueAnimator.AnimatorUpdateListener { + private class MarkerCoordinateAnimatorListener extends AnimatorListenerAdapter implements ValueAnimator.AnimatorUpdateListener { private MyLocationBehavior behavior; private double fromLat; @@ -591,7 +606,7 @@ public void onAnimationUpdate(ValueAnimator animation) { double latitude = fromLat + (toLat - fromLat) * frac; double longitude = fromLng + (toLng - fromLng) * frac; behavior.updateLatLng(latitude, longitude); - updateOnNextFrame(); + update(); } } @@ -732,7 +747,10 @@ void updateLatLng(@NonNull final Location location) { } locationChangeAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); - locationChangeAnimator.setDuration((long) (locationUpdateDuration * 1.2)); + + + long duration = (long) (locationUpdateDuration * 1.5); + locationChangeAnimator.setDuration(duration > MAX_ANIMATION_TIME ? MAX_ANIMATION_TIME : duration); locationChangeAnimator.addUpdateListener(new MarkerCoordinateAnimatorListener(this, previousLocation, interpolatedLocation )); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java index d41c6925094..8b8cd720960 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java @@ -21,8 +21,8 @@ public static MapboxMap getMapboxMap(MapView mapView) { * @param mapView * @param direction */ - public static void setDirection(MapView mapView, double direction) { - mapView.setDirection(direction); + public static void setDirection(MapView mapView, float direction) { + mapView.setBearing(direction); } }