[android] - correct focal point with padding and tilt enabled + cleanup code MyLocationView (#6594)

This commit is contained in:
Tobrun
2016-10-05 22:54:35 +02:00
committed by GitHub
parent dab8ee93c8
commit 8b5228d6ec
2 changed files with 44 additions and 25 deletions

View File

@@ -47,8 +47,14 @@ public class MyLocationView extends View {
private MyLocationBehavior myLocationBehavior;
private MapboxMap mapboxMap;
private Projection projection;
private int[] contentPadding = new int[4];
private float[] projectedCoordinate = new float[2];
private float projectedX;
private float projectedY;
private float contentPaddingX;
private float contentPaddingY;
private Location location;
private LatLng latLng;
@@ -78,9 +84,6 @@ public class MyLocationView extends View {
private Drawable foregroundBearingDrawable;
private Drawable backgroundDrawable;
private int foregroundTintColor;
private int backgroundTintColor;
private Rect foregroundBounds;
private Rect backgroundBounds;
@@ -175,7 +178,6 @@ public class MyLocationView extends View {
public final void setForegroundDrawableTint(@ColorInt int color) {
if (color != Color.TRANSPARENT) {
foregroundTintColor = color;
if (foregroundDrawable != null) {
foregroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
@@ -205,7 +207,6 @@ public class MyLocationView extends View {
public final void setShadowDrawableTint(@ColorInt int color) {
if (color != Color.TRANSPARENT) {
backgroundTintColor = color;
if (backgroundDrawable == null) {
return;
}
@@ -258,33 +259,36 @@ public class MyLocationView extends View {
}
final PointF pointF = screenLocation;
float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude());
float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel / 2;
float maxRadius = getWidth() / 2;
accuracyPixels = accuracyPixels <= maxRadius ? accuracyPixels : maxRadius;
// put matrix in origin
// reset
matrix.reset();
projectedCoordinate[0] = 0;
projectedCoordinate[1] = 0;
// apply tilt to camera
// put camera in position
camera.save();
camera.rotate(tilt, 0, bearing);
// map camera matrix on our matrix
camera.rotate(tilt, 0, 0);
camera.getMatrix(matrix);
//
if (myBearingTrackingMode != MyBearingTracking.NONE && directionAnimator != null) {
matrix.preRotate((Float) directionAnimator.getAnimatedValue());
}
// put matrix at location of MyLocationView
matrix.postTranslate(pointF.x, pointF.y);
matrix.preTranslate(0, contentPaddingY);
matrix.postTranslate(pointF.x, pointF.y - contentPaddingY);
// concat our matrix on canvas
canvas.concat(matrix);
// calculate focal point
matrix.mapPoints(projectedCoordinate);
projectedX = pointF.x - projectedCoordinate[0];
projectedY = pointF.y - projectedCoordinate[1];
// restore orientation from camera
camera.restore();
@@ -308,6 +312,9 @@ public class MyLocationView extends View {
public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) {
this.tilt = (float) tilt;
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
mapboxMap.getUiSettings().setFocalPoint(new PointF(getCenterX(), getCenterY()));
}
}
public void setBearing(double bearing) {
@@ -495,22 +502,23 @@ public class MyLocationView extends View {
}
public float getCenterX() {
return (getX() + contentPadding[0] - contentPadding[2] + getMeasuredWidth()) / 2;
return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX;
}
public float getCenterY() {
return (getY() + contentPadding[1] - contentPadding[3] + getMeasuredHeight()) / 2;
return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY;
}
public void setContentPadding(int[] padding) {
contentPadding = padding;
contentPaddingX = (padding[0] - padding[2]) / 2;
contentPaddingY = (padding[1] - padding[3]) / 2;
}
private static class GpsLocationListener implements LocationListener {
private WeakReference<MyLocationView> userLocationView;
public GpsLocationListener(MyLocationView myLocationView) {
GpsLocationListener(MyLocationView myLocationView) {
userLocationView = new WeakReference<>(myLocationView);
}
@@ -541,7 +549,7 @@ public class MyLocationView extends View {
// Compass data
private long compassUpdateNextTimestamp = 0;
public CompassListener(Context context) {
CompassListener(Context context) {
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
}
@@ -623,7 +631,7 @@ public class MyLocationView extends View {
private class MyLocationBehaviorFactory {
public MyLocationBehavior getBehavioralModel(@MyLocationTracking.Mode int mode) {
MyLocationBehavior getBehavioralModel(@MyLocationTracking.Mode int mode) {
if (mode == MyLocationTracking.TRACKING_NONE) {
return new MyLocationShowBehavior();
} else {
@@ -636,14 +644,14 @@ public class MyLocationView extends View {
abstract void updateLatLng(@NonNull Location location);
public void updateLatLng(double lat, double lon) {
void updateLatLng(double lat, double lon) {
if (latLng != null) {
latLng.setLatitude(lat);
latLng.setLongitude(lon);
}
}
protected void updateAccuracy(@NonNull Location location) {
void updateAccuracy(@NonNull Location location) {
if (accuracyAnimator != null && accuracyAnimator.isRunning()) {
// use current accuracy as a starting point
accuracy = (Float) accuracyAnimator.getAnimatedValue();
@@ -708,8 +716,8 @@ public class MyLocationView extends View {
@Override
void invalidate() {
int[] mapPadding = mapboxMap.getPadding();
float x = (getWidth() + mapPadding[0] - mapPadding[2]) / 2 + (contentPadding[0] - contentPadding[2]) / 2;
float y = (getHeight() - mapPadding[3] + mapPadding[1]) / 2 + (contentPadding[1] - contentPadding[3]) / 2;
float x = (getWidth() + mapPadding[0] - mapPadding[2]) / 2 + contentPaddingX;
float y = (getHeight() - mapPadding[3] + mapPadding[1]) / 2 + contentPaddingY;
screenLocation = new PointF(x, y);
MyLocationView.this.invalidate();
}