[android] - fixup MyLocationView heading (#6671)

[android] - convert angles to radiants in jni, correct follow animation for MyLocationView

do not sanitise input when recreating from other camera object, input is already sanitised before

cleanup mylocationview, made animation bit more smooth, improved UX when switching between tracking modes

cleanup CameraUpdateFactory, hide internally used api.

only invalidate position if required, remove outdated comments

correct camera position values

made zoom activity a bit more interesting

made dynamic marker activity a bit more interesting

FIXUP
This commit is contained in:
Tobrun
2016-10-18 17:56:39 +02:00
committed by GitHub
parent 87885008a6
commit 0ccc7f51ba
9 changed files with 80 additions and 81 deletions

View File

@@ -171,10 +171,10 @@ public final class CameraPosition implements Parcelable {
public Builder(CameraUpdateFactory.CameraPositionUpdate update) {
super();
if (update != null) {
bearing(update.getBearing());
target(update.getTarget());
tilt(update.getTilt());
zoom(update.getZoom());
bearing = update.getBearing();
target = update.getTarget();
tilt = update.getTilt();
zoom = update.getZoom();
}
}
@@ -202,7 +202,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(nativeCameraValues[2]);
tilt(nativeCameraValues[3]);
zoom((float) nativeCameraValues[4]);
}
@@ -217,7 +217,7 @@ public final class CameraPosition implements Parcelable {
public Builder bearing(double bearing) {
double direction = bearing;
while (direction > 360) {
while (direction >= 360) {
direction -= 360;
}
while (direction < 0) {

View File

@@ -200,16 +200,16 @@ public final class CameraUpdateFactory {
private LatLngBounds bounds;
private RectF padding;
public CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
this.bounds = bounds;
this.padding = padding;
}
public CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
}
public CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
this(bounds, new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom});
}
@@ -283,7 +283,7 @@ public final class CameraUpdateFactory {
private float x;
private float y;
public CameraMoveUpdate(float x, float y) {
CameraMoveUpdate(float x, float y) {
this.x = x;
this.y = y;
}
@@ -315,14 +315,14 @@ public final class CameraUpdateFactory {
@IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {
@interface Type {
}
public static final int ZOOM_IN = 0;
public static final int ZOOM_OUT = 1;
public static final int ZOOM_BY = 2;
public static final int ZOOM_TO = 3;
public static final int ZOOM_TO_POINT = 4;
static final int ZOOM_IN = 0;
static final int ZOOM_OUT = 1;
static final int ZOOM_BY = 2;
static final int ZOOM_TO = 3;
static final int ZOOM_TO_POINT = 4;
@Type
private final int type;
@@ -364,7 +364,7 @@ public final class CameraUpdateFactory {
return y;
}
public double transformZoom(double currentZoom) {
double transformZoom(double currentZoom) {
switch (getType()) {
case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
currentZoom++;

View File

@@ -1323,7 +1323,7 @@ public class MapView extends FrameLayout {
return;
}
nativeMapView.cancelTransitions();
nativeMapView.jumpTo(Math.toRadians(-bearing), center, Math.toRadians(pitch), zoom);
nativeMapView.jumpTo(bearing, center, pitch, zoom);
}
void easeTo(double bearing, LatLng center, long duration, double pitch, double zoom, boolean easingInterpolator, @Nullable final MapboxMap.CancelableCallback cancelableCallback) {
@@ -1347,7 +1347,7 @@ public class MapView extends FrameLayout {
});
}
nativeMapView.easeTo(Math.toRadians(-bearing), center, duration, Math.toRadians(pitch), zoom, easingInterpolator);
nativeMapView.easeTo(bearing, center, duration, pitch, zoom, easingInterpolator);
}
void flyTo(double bearing, LatLng center, long duration, double pitch, double zoom, @Nullable final MapboxMap.CancelableCallback cancelableCallback) {
@@ -1371,7 +1371,7 @@ public class MapView extends FrameLayout {
});
}
nativeMapView.flyTo(Math.toRadians(-bearing), center, duration, Math.toRadians(pitch), zoom);
nativeMapView.flyTo(bearing, center, duration, pitch, zoom);
}
private void adjustTopOffsetPixels() {

View File

@@ -389,15 +389,16 @@ public class MapboxMap {
*/
@UiThread
public final void moveCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
// dismiss tracking, moving camera is equal to a gesture
cameraPosition = update.getCameraPosition(this);
mapView.resetTrackingModesIfRequired(cameraPosition);
mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
if (callback != null) {
callback.onFinish();
}
invalidateCameraPosition();
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(this.cameraPosition);
}
}
/**
@@ -560,8 +561,6 @@ public class MapboxMap {
*/
@UiThread
public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
// dismiss tracking, moving camera is equal to a gesture
cameraPosition = update.getCameraPosition(this);
mapView.resetTrackingModesIfRequired(cameraPosition);
mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
@@ -602,15 +601,17 @@ public class MapboxMap {
* Invalidates the current camera position by reconstructing it from mbgl
*/
private void invalidateCameraPosition() {
invalidCameraPosition = false;
if(invalidCameraPosition) {
invalidCameraPosition = false;
CameraPosition cameraPosition = mapView.invalidateCameraPosition();
if (cameraPosition != null) {
this.cameraPosition = cameraPosition;
}
CameraPosition cameraPosition = mapView.invalidateCameraPosition();
if (cameraPosition != null) {
this.cameraPosition = cameraPosition;
}
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(this.cameraPosition);
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(this.cameraPosition);
}
}
}

View File

@@ -55,13 +55,9 @@ public class MyLocationView extends View {
private float contentPaddingX;
private float contentPaddingY;
private Location location;
private LatLng latLng;
private LatLng interpolatedLocation;
private LatLng previousLocation;
private Location location;
private long locationUpdateTimestamp;
private float gpsDirection;
private float previousDirection;
private float accuracy;
@@ -454,27 +450,29 @@ public class MyLocationView extends View {
compassListener.onPause();
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
// always face north
gpsDirection = bearing;
setCompass(gpsDirection);
setCompass(0);
}
}
invalidate();
update();
}
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
MyLocationBehaviorFactory factory = new MyLocationBehaviorFactory();
myLocationBehavior = factory.getBehavioralModel(myLocationTrackingMode);
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW && location != null) {
// center map directly if we have a location fix
if (location != null) {
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
// center map directly
mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false /*linear interpolator*/, false /*do not disable tracking*/, null);
} else {
// do not use interpolated location from tracking mode
latLng = null;
}
myLocationBehavior.updateLatLng(location);
mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false /*linear interpolator*/, false /*do not disable tracking*/, null);
}
this.myLocationTrackingMode = myLocationTrackingMode;
invalidate();
update();
}
private void setCompass(float bearing) {
@@ -641,7 +639,9 @@ public class MyLocationView extends View {
private abstract class MyLocationBehavior {
abstract void updateLatLng(@NonNull Location location);
void updateLatLng(@NonNull Location newLocation) {
location = newLocation;
}
void updateLatLng(double lat, double lon) {
if (latLng != null) {
@@ -670,6 +670,7 @@ public class MyLocationView extends View {
@Override
void updateLatLng(@NonNull Location location) {
super.updateLatLng(location);
if (latLng == null) {
// first location fix
latLng = new LatLng(location);
@@ -677,39 +678,34 @@ public class MyLocationView extends View {
}
// updateLatLng timestamp
long previousUpdateTimeStamp = locationUpdateTimestamp;
float previousUpdateTimeStamp = locationUpdateTimestamp;
locationUpdateTimestamp = SystemClock.elapsedRealtime();
// calculate animation duration
long locationUpdateDuration;
float animationDuration;
if (previousUpdateTimeStamp == 0) {
locationUpdateDuration = 0;
animationDuration = 0;
} else {
locationUpdateDuration = locationUpdateTimestamp - previousUpdateTimeStamp;
animationDuration = (locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f /*make animation slightly longer*/;
}
// calculate interpolated location
previousLocation = latLng;
latLng = new LatLng(location);
interpolatedLocation = new LatLng(latLng.getLatitude() , latLng.getLongitude());
// build new camera
CameraPosition.Builder builder = new CameraPosition.Builder().target(interpolatedLocation);
CameraPosition.Builder builder = new CameraPosition.Builder().target(latLng);
// add direction
if (myBearingTrackingMode == MyBearingTracking.GPS) {
if (location.hasBearing()) {
builder.bearing(location.getBearing());
}
gpsDirection = location.getBearing();
setCompass(gpsDirection);
setCompass(0);
}
// accuracy
updateAccuracy(location);
// ease to new camera position with a linear interpolator
mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) locationUpdateDuration, false /*linear interpolator*/, false /*do not disable tracking*/, null);
mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) animationDuration, false /*linear interpolator*/, false /*do not disable tracking*/, null);
}
@Override
@@ -726,6 +722,7 @@ public class MyLocationView extends View {
@Override
void updateLatLng(@NonNull final Location location) {
super.updateLatLng(location);
if (latLng == null) {
// first location update
latLng = new LatLng(location);
@@ -733,13 +730,11 @@ public class MyLocationView extends View {
}
// update LatLng location
previousLocation = latLng;
latLng = new LatLng(location);
LatLng newLocation = new LatLng(location);
// update LatLng direction
if (myBearingTrackingMode == MyBearingTracking.GPS && location.hasBearing()) {
gpsDirection = location.getBearing();
setCompass(gpsDirection);
setCompass(location.getBearing() + bearing);
}
// update LatLng accuracy
@@ -748,10 +743,7 @@ public class MyLocationView extends View {
// calculate updateLatLng time + add some extra offset to improve animation
long previousUpdateTimeStamp = locationUpdateTimestamp;
locationUpdateTimestamp = SystemClock.elapsedRealtime();
long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.3);
// calculate interpolated entity
interpolatedLocation = new LatLng(latLng.getLatitude() , latLng.getLongitude());
long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.2f);
// animate changes
if (locationChangeAnimator != null) {
@@ -760,14 +752,12 @@ public class MyLocationView extends View {
}
locationChangeAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
locationChangeAnimator.setDuration((long) (locationUpdateDuration * 1.2));
locationChangeAnimator.setDuration(locationUpdateDuration);
locationChangeAnimator.addUpdateListener(new MarkerCoordinateAnimatorListener(this,
previousLocation, interpolatedLocation
latLng, newLocation
));
locationChangeAnimator.start();
// use interpolated location as current location
latLng = interpolatedLocation;
latLng = newLocation;
}
@Override