From b778043f3ea66b7f8e86f847e33fa7b0b10e49ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Wed, 21 Feb 2018 18:53:46 +0100 Subject: [PATCH 01/13] initial LocationLayerPlugin cleanup --- .../location/CompassListenerActivity.java | 2 +- .../location/LocationLayerModesActivity.java | 2 +- .../plugins/locationlayer/CompassManager.java | 60 +-- .../locationlayer/LocationLayerPlugin.java | 472 +++++------------- .../OnLocationStaleListener.java | 4 +- .../locationlayer/StaleStateRunnable.java | 57 +-- 6 files changed, 168 insertions(+), 429 deletions(-) diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java index 5e94b7622..34e6bbb06 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java @@ -95,7 +95,7 @@ public void onLowMemory() { protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); - locationLayerPlugin.removeCompassListener(null); + locationLayerPlugin.removeCompassListener(); } @Override diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java index 598a4db0d..56b63551c 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java @@ -91,7 +91,7 @@ public void onMapReady(MapboxMap mapboxMap) { locationEngine.addLocationEngineListener(this); locationEngine.activate(); locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); - locationLayerPlugin.setOnLocationClickListener(this); + locationLayerPlugin.addOnLocationClickListener(this); locationLayerPlugin.setLocationLayerEnabled(true); getLifecycle().addObserver(locationLayerPlugin); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java index 4f07c5055..39b59026a 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java @@ -33,14 +33,14 @@ class CompassManager implements SensorEventListener { private final WindowManager windowManager; private final SensorManager sensorManager; - private CompassListener internalCompassListener; - private List compassListeners; + private final List compassListeners = new ArrayList<>(); // Not all devices have a compassSensor @Nullable private Sensor compassSensor; private int lastAccuracy; + private float lastHeading; // CompassManager data private long compassUpdateNextTimestamp; @@ -49,10 +49,7 @@ class CompassManager implements SensorEventListener { * Construct a new instance of the this class. A internal compass listeners needed to separate it * from the cleared list of public listeners. */ - CompassManager(@NonNull Context context, @NonNull CompassListener internalCompassListener) { - this.internalCompassListener = internalCompassListener; - compassListeners = new ArrayList<>(); - + CompassManager(@NonNull Context context) { windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); @@ -65,28 +62,30 @@ class CompassManager implements SensorEventListener { } void addCompassListener(@NonNull CompassListener compassListener) { + if (compassListeners.isEmpty()) { + onStart(); + } compassListeners.add(compassListener); } - void removeCompassListener(@Nullable CompassListener compassListener) { - if (compassListener == null) { - compassListeners.clear(); - return; - } + void removeCompassListener(@NonNull CompassListener compassListener) { compassListeners.remove(compassListener); - } - - List getCompassListeners() { - return compassListeners; + if (compassListeners.isEmpty()) { + onStop(); + } } void onStart() { - // Does nothing if the sensors already registered. - sensorManager.registerListener(this, compassSensor, SENSOR_DELAY_MICROS); + if (isSensorAvailable()) { + // Does nothing if the sensors already registered. + sensorManager.registerListener(this, compassSensor, SENSOR_DELAY_MICROS); + } } void onStop() { - sensorManager.unregisterListener(this, compassSensor); + if (isSensorAvailable()) { + sensorManager.unregisterListener(this, compassSensor); + } } boolean isSensorAvailable() { @@ -95,9 +94,6 @@ boolean isSensorAvailable() { @Override public void onSensorChanged(SensorEvent event) { - if (internalCompassListener == null) { - return; - } // check when the last time the compass was updated, return if too soon. long currentTime = SystemClock.elapsedRealtime(); if (currentTime < compassUpdateNextTimestamp) { @@ -113,17 +109,13 @@ public void onSensorChanged(SensorEvent event) { // Update the compassUpdateNextTimestamp compassUpdateNextTimestamp = currentTime + LocationLayerConstants.COMPASS_UPDATE_RATE_MS; } else if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) { - internalCompassListener.onCompassChanged((event.values[0] + 360) % 360); - for (CompassListener compassListener : compassListeners) { - compassListener.onCompassChanged((event.values[0] + 360) % 360); - } + notifyCompassChangeListeners((event.values[0] + 360) % 360); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { if (lastAccuracy != accuracy) { - internalCompassListener.onCompassAccuracyChange(accuracy); for (CompassListener compassListener : compassListeners) { compassListener.onCompassAccuracyChange(accuracy); } @@ -170,9 +162,21 @@ private void updateOrientation(float[] rotationVector) { SensorManager.getOrientation(adjustedRotationMatrix, orientation); // The x-axis is all we care about here. - internalCompassListener.onCompassChanged((float) Math.toDegrees(orientation[0])); + notifyCompassChangeListeners((float) Math.toDegrees(orientation[0])); + } + + private void notifyCompassChangeListeners(float heading) { + lastHeading = heading; for (CompassListener compassListener : compassListeners) { - compassListener.onCompassChanged((float) Math.toDegrees(orientation[0])); + compassListener.onCompassChanged(heading); } } + + int getLastAccuracy() { + return lastAccuracy; + } + + float getLastHeading() { + return lastHeading; + } } \ No newline at end of file diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index de1ed3cb0..5231c81f9 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -1,18 +1,15 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; -import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.arch.lifecycle.Lifecycle; import android.arch.lifecycle.LifecycleObserver; import android.arch.lifecycle.OnLifecycleEvent; import android.location.Location; -import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresPermission; import android.support.annotation.StyleRes; import android.support.v7.app.AppCompatDelegate; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.view.animation.LinearInterpolator; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; @@ -21,21 +18,16 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener; import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener; -import com.mapbox.mapboxsdk.plugins.locationlayer.camera.LocationLayerCamera; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; import com.mapbox.services.commons.geojson.Point; +import java.util.concurrent.CopyOnWriteArrayList; + import timber.log.Timber; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_LAYER; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.BEARING_LAYER; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.COMPASS_UPDATE_RATE_MS; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.MAX_ANIMATION_DURATION_MS; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.NAVIGATION_LAYER; -import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.shortestRotation; /** * The Location layer plugin provides location awareness to your mobile application. Enabling this @@ -61,33 +53,21 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas OnMapChangedListener, LifecycleObserver, OnCameraMoveListener, OnMapClickListener, OnLocationStaleListener { - private LocationLayer locationLayer; - private CompassManager compassManager; - private LocationEngine locationEngine; - private LocationLayerCamera camera; private final MapboxMap mapboxMap; private final MapView mapView; + private LocationLayerOptions options; + private LocationLayer locationLayer; + private LocationEngine locationEngine; + private CompassManager compassManager; - // Enabled booleans - @LocationLayerMode.Mode - private int locationLayerMode; - private boolean isEnabled; - - // Previous compass and location values - private float previousMagneticHeading; - private Point previousPoint; - private Location location; - - // Animators - private ValueAnimator locationChangeAnimator; - private ValueAnimator bearingChangeAnimator; - - private long locationUpdateTimestamp; - private boolean linearAnimation; + // TODO: 21/02/2018 references to animator, LL and camera - private OnLocationLayerClickListener onLocationLayerClickListener; + private boolean isEnabled; private StaleStateRunnable staleStateRunnable; - private LocationLayerOptions options; + private final CopyOnWriteArrayList onLocationStaleListeners + = new CopyOnWriteArrayList<>(); + private final CopyOnWriteArrayList onLocationLayerClickListeners + = new CopyOnWriteArrayList<>(); /** * Construct a {@code LocationLayerPlugin} @@ -116,7 +96,6 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa @Nullable LocationEngine locationEngine, @StyleRes int styleRes) { this(mapView, mapboxMap, locationEngine, LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes)); - } public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap, @@ -126,23 +105,25 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa this.mapboxMap = mapboxMap; this.mapView = mapView; this.options = options; - mapView.addOnMapChangedListener(this); initialize(); } private void initialize() { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); - staleStateRunnable = new StaleStateRunnable(options.staleStateDelay()); - locationLayerMode = LocationLayerMode.NORMAL; + + mapView.addOnMapChangedListener(this); + mapboxMap.addOnMapClickListener(this); + locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable); - compassManager = new CompassManager(mapView.getContext(), this); - camera = new LocationLayerCamera(mapboxMap); + compassManager = new CompassManager(mapView.getContext()); + compassManager.addCompassListener(this); + staleStateRunnable = new StaleStateRunnable(this, options.staleStateDelay()); + enableLocationLayerPlugin(); } @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}) public void setLocationLayerEnabled(boolean isEnabled) { - this.isEnabled = isEnabled; if (isEnabled) { enableLocationLayerPlugin(); } else { @@ -150,6 +131,25 @@ public void setLocationLayerEnabled(boolean isEnabled) { } } + private void enableLocationLayerPlugin() { + isEnabled = true; + + if (locationEngine != null) { + locationEngine.addLocationEngineListener(this); + } + setLastLocation(); + locationLayer.setLayersVisibility(true); + } + + private void disableLocationLayerPlugin() { + isEnabled = false; + + if (locationEngine != null) { + locationEngine.removeLocationEngineListener(this); + } + locationLayer.setLayersVisibility(false); + } + /** * After creating an instance of this plugin, you can use this API to enable the location mode of * your choice. These modes can be found in the {@link LocationLayerMode} class and the parameter @@ -165,27 +165,9 @@ public void setLocationLayerEnabled(boolean isEnabled) { * @param locationLayerMode one of the modes found in {@link LocationLayerMode} * @since 0.1.0 */ - public void setLocationLayerMode(@LocationLayerMode.Mode int locationLayerMode) { - this.locationLayerMode = locationLayerMode; - if (locationLayerMode == LocationLayerMode.COMPASS) { - setLinearAnimation(false); - setNavigationEnabled(false); - setMyBearingEnabled(true); - } else if (locationLayerMode == LocationLayerMode.NAVIGATION) { - setMyBearingEnabled(false); - setNavigationEnabled(true); - } else if (locationLayerMode == LocationLayerMode.NORMAL) { - setLinearAnimation(false); - setMyBearingEnabled(false); - setNavigationEnabled(false); - } - } + // TODO: 21/02/2018 set render mode and camera mode - public void setLocationLayerTracking(@LocationLayerTracking.Type int trackingMode) { - if (camera != null) { - camera.setTrackingMode(trackingMode); - } - } + // TODO: 21/02/2018 return current render mode and camera mode /** * Returns the current location mode being used with this plugin. @@ -193,10 +175,6 @@ public void setLocationLayerTracking(@LocationLayerTracking.Type int trackingMod * @return on of the {@link LocationLayerMode} values * @since 0.1.0 */ - public int getLocationLayerMode() { - return locationLayerMode; - } - public LocationLayerOptions getLocationLayerOptions() { return options; } @@ -204,16 +182,20 @@ public LocationLayerOptions getLocationLayerOptions() { @Override public void onMapChanged(int change) { if (change == MapView.WILL_START_LOADING_MAP) { - stopAllAnimations(); + // TODO: 21/02/2018 stop animations, notify anyone interested } else if (change == MapView.DID_FINISH_LOADING_STYLE) { mapStyleFinishedLoading(); } } @Override - public void isLocationStale(boolean stale) { - Timber.v("isLocationStale: %b", stale); - locationLayer.locationsStale(stale); + public void onStaleStateChange(boolean isStale) { + Timber.v("onStaleStateChange: %b", isStale); + locationLayer.locationsStale(isStale); + + for (OnLocationStaleListener listener : onLocationStaleListeners) { + listener.onStaleStateChange(isStale); + } } /** @@ -229,7 +211,7 @@ public void applyStyle(@StyleRes int styleRes) { public void applyStyle(LocationLayerOptions options) { locationLayer.applyStyle(options); if (!options.enableStaleState()) { - staleStateRunnable.reset(); + staleStateRunnable.onStop(); } staleStateRunnable.setDelayTime(options.staleStateDelay()); } @@ -243,7 +225,6 @@ public void applyStyle(LocationLayerOptions options) { */ public void forceLocationUpdate(@Nullable Location location) { updateLocation(location); - updateCameraLocation(location); } /** @@ -258,7 +239,6 @@ public void forceLocationUpdate(@Nullable Location location) { public void setLocationEngine(@Nullable LocationEngine locationEngine) { if (locationEngine != null) { this.locationEngine = locationEngine; - setLocationLayerMode(locationLayerMode); } else if (this.locationEngine != null) { this.locationEngine.removeLocationEngineListener(this); this.locationEngine = null; @@ -276,26 +256,6 @@ public LocationEngine getLocationEngine() { return locationEngine; } - /** - * Required to place inside your activities {@code onStop} method. - * - * @since 0.1.0 - */ - @OnLifecycleEvent(Lifecycle.Event.ON_STOP) - public void onStop() { - staleStateRunnable.onStop(); - stopAllAnimations(); - if (compassManager != null && compassManager.isSensorAvailable()) { - compassManager.onStop(); - } - if (locationEngine != null) { - locationEngine.removeLocationEngineListener(this); - } - if (mapboxMap != null) { - mapboxMap.removeOnCameraMoveListener(this); - } - } - /** * Required to place inside your activities {@code onStart} method. You'll also most likely want * to check that this Location Layer plugin instance inside your activity is null or not. @@ -306,41 +266,37 @@ public void onStop() { @OnLifecycleEvent(Lifecycle.Event.ON_START) public void onStart() { if (isEnabled) { - setLocationLayerMode(locationLayerMode); - } - - if (!compassManager.getCompassListeners().isEmpty() - || (locationLayerMode == LocationLayerMode.COMPASS && compassManager.isSensorAvailable())) { - compassManager.onStart(); + if (locationEngine != null) { + locationEngine.addLocationEngineListener(this); + } + setLastLocation(); + // TODO: 21/02/2018 reset modes } if (mapboxMap != null) { mapboxMap.addOnCameraMoveListener(this); } - staleStateRunnable.addOnLocationStaleListener(this); - } - - /** - * Check whether the location update animator is using a linear or an accelerate/decelerate - * interpolator. When the navigation mode is being used, the animator automatically become linear. - * - * @return boolean true if the location update animator is set to linear, otherwise false - * @since 0.1.0 - */ - public boolean isLinearAnimation() { - return linearAnimation; + if (options.enableStaleState()) { + staleStateRunnable.onStart(); + } + compassManager.onStart(); } /** - * Set whether the location update animator is using linear (true) or an accelerate/decelerate - * (false) interpolator. When the navigation mode is being used, the animator automatically become - * linear. + * Required to place inside your activities {@code onStop} method. * - * @param linearAnimation boolean true if you'd like to set the location update animator to - * linear, otherwise false * @since 0.1.0 */ - public void setLinearAnimation(boolean linearAnimation) { - this.linearAnimation = linearAnimation; + @OnLifecycleEvent(Lifecycle.Event.ON_STOP) + public void onStop() { + staleStateRunnable.onStop(); + compassManager.onStop(); + // TODO: 21/02/2018 stop animations + if (locationEngine != null) { + locationEngine.removeLocationEngineListener(this); + } + if (mapboxMap != null) { + mapboxMap.removeOnCameraMoveListener(this); + } } /** @@ -353,20 +309,16 @@ public void setLinearAnimation(boolean linearAnimation) { */ public void addCompassListener(@NonNull CompassListener compassListener) { compassManager.addCompassListener(compassListener); - compassManager.onStart(); } /** - * Remove either a single instance of compass listener or all the listeners using null. + * Remove a compass listener. * * @param compassListener the {@link CompassListener} which you'd like to remove from the listener - * list. You can optionally pass in null to remove all listeners + * list. */ - public void removeCompassListener(@Nullable CompassListener compassListener) { + public void removeCompassListener(@NonNull CompassListener compassListener) { compassManager.removeCompassListener(compassListener); - if (compassManager.getCompassListeners().isEmpty()) { - compassManager.onStop(); - } } /** @@ -376,18 +328,28 @@ public void removeCompassListener(@Nullable CompassListener compassListener) { * location layer is clicked * @since 0.3.0 */ - public void setOnLocationClickListener( - @Nullable OnLocationLayerClickListener locationClickListener) { - this.onLocationLayerClickListener = locationClickListener; - if (onLocationLayerClickListener != null) { - mapboxMap.addOnMapClickListener(this); - } + public void addOnLocationClickListener(@NonNull OnLocationLayerClickListener locationClickListener) { + onLocationLayerClickListeners.add(locationClickListener); + } + + public void removeOnLocationClickListener(@NonNull OnLocationLayerClickListener locationClickListener) { + onLocationLayerClickListeners.remove(locationClickListener); + } + + public void addOnLocationStaleListener(@NonNull OnLocationStaleListener listener) { + onLocationStaleListeners.add(listener); + } + + public void removeOnLocationStaleListener(@NonNull OnLocationStaleListener listener) { + onLocationStaleListeners.remove(listener); } @Override public void onMapClick(@NonNull LatLng point) { - if (onLocationLayerClickListener != null && locationLayer.onMapClick(point)) { - onLocationLayerClickListener.onLocationLayerClick(); + if (!onLocationLayerClickListeners.isEmpty() && locationLayer.onMapClick(point)) { + for (OnLocationLayerClickListener listener : onLocationLayerClickListeners) { + listener.onLocationLayerClick(); + } } } @@ -402,12 +364,11 @@ public void onConnected() { @Override public void onLocationChanged(Location location) { updateLocation(location); - updateCameraLocation(location); } @Override public void onCompassChanged(float userHeading) { - bearingChangeAnimate(userHeading); + updateCompassHeading(userHeading); } @Override @@ -415,94 +376,30 @@ public void onCompassAccuracyChange(int compassStatus) { // Currently don't handle this inside SDK } - private void toggleCameraListener() { - if (locationLayerMode == LocationLayerMode.NAVIGATION) { - mapboxMap.removeOnCameraMoveListener(this); - return; - } - mapboxMap.addOnCameraMoveListener(this); - } - - private void updateLocation(Location location) { - this.location = location; - if (location == null) { - locationUpdateTimestamp = SystemClock.elapsedRealtime(); - return; - } - if (locationLayerMode == LocationLayerMode.NAVIGATION && location.hasBearing()) { - bearingChangeAnimate(location.getBearing()); - } else if (locationLayerMode != LocationLayerMode.NAVIGATION) { - locationLayer.updateAccuracyRadius(location); - } - setLocation(location); - } - - private void updateCameraLocation(Location location) { - if (camera != null) { - camera.moveToLocation(location); - } - } - - private void enableLocationLayerPlugin() { - // Set an initial location if one is available and the locationEngines not null - if (locationEngine != null) { - setLastLocation(); - locationEngine.addLocationEngineListener(this); - } - - toggleCameraListener(); - locationLayer.setLayersVisibility(true); - } - - /** - * disable the location layer plugin if the locationLayerMode is set to none. - */ - private void disableLocationLayerPlugin() { - if (locationEngine != null) { - locationEngine.removeLocationEngineListener(this); - } - locationLayer.setLayersVisibility(false); - } - /** * If the locationEngine contains a last location value, we use it for the initial location layer * position. */ @SuppressWarnings( {"MissingPermission"}) private void setLastLocation() { - Location lastLocation = locationEngine.getLastLocation(); - if (lastLocation != null) { - setLocation(lastLocation); - if (locationLayerMode != LocationLayerMode.NAVIGATION) { - locationLayer.updateAccuracyRadius(lastLocation); - } + if (locationEngine != null) { + updateLocation(locationEngine.getLastLocation()); } } + private void setLastCompassHeading() { + updateCompassHeading(compassManager.getLastHeading()); + } + /** * Get the last know location of the location layer plugin. * * @return the last known location */ + @SuppressLint("MissingPermission") @Nullable public Location getLastKnownLocation() { - return location; - } - - /** - * Convenience method for stopping all animations - */ - private void stopAllAnimations() { - if (locationChangeAnimator != null) { - locationChangeAnimator.removeAllListeners(); - locationChangeAnimator.cancel(); - locationChangeAnimator = null; - } - if (bearingChangeAnimator != null) { - bearingChangeAnimator.removeAllListeners(); - bearingChangeAnimator.cancel(); - bearingChangeAnimator = null; - } + return locationEngine != null ? locationEngine.getLastLocation() : null; } /** @@ -513,58 +410,15 @@ private void stopAllAnimations() { private void mapStyleFinishedLoading() { // recreate runtime style components locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable); - // reset state - setLocationLayerMode(locationLayerMode); - setBearing(previousMagneticHeading); - updateCameraBearing(previousMagneticHeading); - if (previousPoint != null) { - locationLayer.setLocationPoint(previousPoint); - } - } + // TODO: 21/02/2018 reset state + setLastLocation(); - /** - * Enable or disable the My Location bearing by passing in a boolean here. Once enabled, The users - * location and bearing's indicated on the map by default as a small blue dot with a chevron - * pointing in the direction of the devices compass bearing. - * - * @param bearingEnabled boolean true if you'd like to enable the user location bearing, - * otherwise, false will disable - * @since 0.1.0 - */ - private void setMyBearingEnabled(boolean bearingEnabled) { - locationLayer.setLayerVisibility(BEARING_LAYER, bearingEnabled); - if (bearingEnabled) { - compassManager.onStart(); - } else { - if (compassManager != null && compassManager.getCompassListeners().isEmpty()) { - compassManager.onStop(); - } - } - } - - /** - * Enable or disable the My Location navigation by passing in a boolean here. Once enabled, The - * users location indicated on the map will show (by default) as a large navigation puck with a - * cheveron/arrow showing the users GPS location bearing. - * - * @param navigationEnabled boolean true if you'd like to enable the user location navigation, - * disable otherwise, false will - * @since 0.1.0 - */ - private void setNavigationEnabled(boolean navigationEnabled) { - setNavigationLayerVisibility(navigationEnabled); - setLinearAnimation(navigationEnabled); - locationLayer.setLayerVisibility(ACCURACY_LAYER, !navigationEnabled); - } - - private void setNavigationLayerVisibility(boolean visible) { - locationLayer.setLayerVisibility(NAVIGATION_LAYER, visible); } @Override public void onCameraMove() { CameraPosition position = mapboxMap.getCameraPosition(); - locationLayer.updateAccuracyRadius(location); + locationLayer.updateAccuracyRadius(getLastKnownLocation()); locationLayer.updateForegroundOffset(position.tilt); locationLayer.updateForegroundBearing((float) position.bearing); } @@ -575,121 +429,23 @@ public void onCameraMove() { * @param location the latest user location * @since 0.1.0 */ - private void setLocation(final Location location) { - this.location = location; + private void updateLocation(final Location location) { + if (location == null) { + return; + } + staleStateRunnable.updateLatestLocationTime(); // Convert the new location to a Point object. Point newPoint = Point.fromCoordinates(new double[] {location.getLongitude(), location.getLatitude()}); - // If the source doesn't have geometry, a Point gets added. - if (previousPoint == null) { - locationLayer.setLocationPoint(newPoint); - previousPoint = newPoint; - return; - } - - // Do nothing if the location source's current Point is identical to the new location Point. - if (previousPoint.getCoordinates().equals(newPoint.getCoordinates())) { - return; - } - locationChangeAnimate(previousPoint, newPoint); - } - - /* - * Animators - */ - - /** - * Handles the animation from currentSourcePoint to the new user location point. - */ - private void locationChangeAnimate(@NonNull Point currentSourcePoint, @NonNull Point newPoint) { - if (locationChangeAnimator != null) { - locationChangeAnimator.end(); - } - - locationChangeAnimator = ValueAnimator.ofObject(new Utils.PointEvaluator(), currentSourcePoint, - newPoint); - - float speed = location == null ? 0 : location.getSpeed(); - - locationChangeAnimator.setDuration(linearAnimation || speed > 0 - ? getLocationUpdateDuration() : LocationLayerConstants.LOCATION_UPDATE_DELAY_MS); - if (linearAnimation || speed > 0) { - locationChangeAnimator.setInterpolator(new LinearInterpolator()); - } else { - locationChangeAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); - } - locationChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - previousPoint = (Point) animation.getAnimatedValue(); - locationLayer.setLocationPoint(previousPoint); - } - }); - locationChangeAnimator.start(); - } - - /** - * Handles the animation from the previous user bearing to the current. - * - * @param magneticHeading the raw compass heading - * @since 0.1.0 - */ - private void bearingChangeAnimate(float magneticHeading) { - if (bearingChangeAnimator != null) { - previousMagneticHeading = (Float) bearingChangeAnimator.getAnimatedValue(); - bearingChangeAnimator.end(); - bearingChangeAnimator = null; - } - - // Always rotate the bearing shortest distance - magneticHeading = shortestRotation(magneticHeading, previousMagneticHeading); - - // No visible change occurred - if (Math.abs(magneticHeading - previousMagneticHeading) < 1) { - return; - } - - bearingChangeAnimator = ValueAnimator.ofFloat(previousMagneticHeading, magneticHeading); - bearingChangeAnimator.setDuration(COMPASS_UPDATE_RATE_MS); - bearingChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator valueAnimator) { - float bearing = (float) valueAnimator.getAnimatedValue(); - setBearing(bearing); - updateCameraBearing(bearing); - } - }); - bearingChangeAnimator.start(); - previousMagneticHeading = magneticHeading; - } - - private void updateCameraBearing(float bearing) { - if (camera != null) { - camera.updateBearing(bearing); - } - } + locationLayer.setLocationPoint(newPoint); - private void setBearing(float bearing) { - locationLayer.setLayerBearing( - locationLayerMode == LocationLayerMode.NAVIGATION - ? NAVIGATION_LAYER : BEARING_LAYER, bearing - ); + // TODO: 21/02/2018 notify animator class about new location } - /** - * Internal method being used to calculate the time duration for the location change animator. - * - * @return millisecond time value as a long value - * @since 0.1.0 - */ - private long getLocationUpdateDuration() { - // calculate updateLatLng time + add some extra offset to improve animation - long previousUpdateTimeStamp = locationUpdateTimestamp; - locationUpdateTimestamp = SystemClock.elapsedRealtime(); - long duration = locationUpdateTimestamp - previousUpdateTimeStamp; - return duration < MAX_ANIMATION_DURATION_MS ? duration : MAX_ANIMATION_DURATION_MS; + private void updateCompassHeading(float heading) { + // TODO: 21/02/2018 notify animator class about new heading } } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationStaleListener.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationStaleListener.java index a872f5fee..99a1a6d2e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationStaleListener.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationStaleListener.java @@ -1,7 +1,5 @@ package com.mapbox.mapboxsdk.plugins.locationlayer; public interface OnLocationStaleListener { - - void isLocationStale(boolean stale); - + void onStaleStateChange(boolean isStale); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateRunnable.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateRunnable.java index 56f2f3dff..0f288a36d 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateRunnable.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateRunnable.java @@ -10,41 +10,27 @@ * Class controls the location layer stale state when the {@link android.location.Location} hasn't * been updated in 'x' amount of time. {@link LocationLayerOptions#staleStateDelay()} can be used to * control the amount of time before the locations considered stale. - * {@link LocationLayerOptions#enableStaleState()} is avaliable for disabling this behaviour. + * {@link LocationLayerOptions#enableStaleState()} is available for disabling this behaviour. * * @since 0.4.0 */ class StaleStateRunnable implements Runnable { - private final List onLocationStaleListeners; + private final OnLocationStaleListener innerOnLocationStaleListeners; private final Handler handler; private boolean isStale; private long delayTime; - StaleStateRunnable(long delayTime) { + StaleStateRunnable(OnLocationStaleListener innerListener, long delayTime) { + innerOnLocationStaleListeners = innerListener; this.delayTime = delayTime; - onLocationStaleListeners = new ArrayList<>(); handler = new Handler(); } - void addOnLocationStaleListener(@NonNull OnLocationStaleListener onLocationStaleListener) { - onLocationStaleListeners.add(onLocationStaleListener); - } - - void removeOnLocationStaleListener(@NonNull OnLocationStaleListener onLocationStaleListener) { - onLocationStaleListeners.remove(onLocationStaleListener); - } - - void removeAllListeners() { - onLocationStaleListeners.clear(); - } - @Override public void run() { - for (OnLocationStaleListener listener : onLocationStaleListeners) { - listener.isLocationStale(true); - } isStale = true; + innerOnLocationStaleListeners.onStaleStateChange(true); } boolean isStale() { @@ -52,33 +38,28 @@ boolean isStale() { } void updateLatestLocationTime() { - for (OnLocationStaleListener listener : onLocationStaleListeners) { - listener.isLocationStale(false); + if (isStale) { + isStale = false; + innerOnLocationStaleListeners.onStaleStateChange(false); } - isStale = false; - handler.removeCallbacks(this); - handler.postDelayed(this, delayTime); - } - /** - * Reset the stale state when {@link LocationLayerOptions#enableStaleState()} is set to false. - * - * @since 0.4.0 - */ - void reset() { - for (OnLocationStaleListener listener : onLocationStaleListeners) { - listener.isLocationStale(false); - } - isStale = false; - handler.removeCallbacks(this); + handler.removeCallbacksAndMessages(this); + handler.postDelayed(this, delayTime); } void setDelayTime(long delayTime) { this.delayTime = delayTime; + handler.removeCallbacksAndMessages(this); + handler.postDelayed(this, delayTime); + } + + void onStart() { + if (!isStale) { + handler.postDelayed(this, delayTime); + } } void onStop() { - removeAllListeners(); - handler.removeCallbacks(this); + handler.removeCallbacksAndMessages(this); } } From 2da22465e9b52e73bfb62545a6589aa8c540ccb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 13:55:03 +0100 Subject: [PATCH 02/13] added the animator class --- .../locationlayer/LocationLayerAnimator.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java new file mode 100644 index 000000000..ef3934e95 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java @@ -0,0 +1,106 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import android.animation.ValueAnimator; +import android.location.Location; +import android.support.annotation.NonNull; + +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.plugins.locationlayer.camera.BearingAnimator; +import com.mapbox.mapboxsdk.plugins.locationlayer.camera.LatLngAnimator; + +import java.util.ArrayList; +import java.util.List; + +final class LocationLayerAnimator { + private final List listeners = new ArrayList<>(); + private LatLngAnimator latLngAnimator; + private BearingAnimator gpsBearingAnimator; + private BearingAnimator compassBearingAnimator; + + void addListener(OnAnimationsValuesChangeListener listener) { + listeners.add(listener); + } + + void removeListener(OnAnimationsValuesChangeListener listener) { + listeners.remove(listener); + } + + void feedNewLocation(@NonNull Location location) { + cancelLocationAnimations(); + LatLng latLng = new LatLng(location); + latLngAnimator = new LatLngAnimator(latLng, 1000); + gpsBearingAnimator = new BearingAnimator(location.getBearing(), 1000); + // FIXME: 22/02/2018 evaluate duration of animation better + + latLngAnimator.addUpdateListener(latLngUpdateListener); + gpsBearingAnimator.addUpdateListener(gpsBearingUpdateListener); + + latLngAnimator.start(); + gpsBearingAnimator.start(); + } + + void feedNewCompassBearing(float compassBearing) { + cancelCompassAnimations(); + compassBearingAnimator = new BearingAnimator(compassBearing, 1000); + // FIXME: 22/02/2018 evaluate duration of animation better + + compassBearingAnimator.addUpdateListener(compassBearingUpdateListener); + compassBearingAnimator.start(); + } + + private final ValueAnimator.AnimatorUpdateListener latLngUpdateListener = new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (OnAnimationsValuesChangeListener listener : listeners) { + listener.onNewLatLngValue((LatLng) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener compassBearingUpdateListener = new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (OnAnimationsValuesChangeListener listener : listeners) { + listener.onNewCompassBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + private final ValueAnimator.AnimatorUpdateListener gpsBearingUpdateListener = new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + for (OnAnimationsValuesChangeListener listener : listeners) { + listener.onNewGpsBearingValue((Float) valueAnimator.getAnimatedValue()); + } + } + }; + + interface OnAnimationsValuesChangeListener { + void onNewLatLngValue(LatLng latLng); + + void onNewGpsBearingValue(float gpsBearing); + + void onNewCompassBearingValue(float compassBearing); + } + + void cancelAllAnimations() { + cancelLocationAnimations(); + cancelCompassAnimations(); + } + + private void cancelLocationAnimations() { + if (latLngAnimator != null) { + latLngAnimator.cancel(); + } + + if (gpsBearingAnimator != null) { + gpsBearingAnimator.cancel(); + } + } + + private void cancelCompassAnimations() { + if (compassBearingAnimator != null) { + compassBearingAnimator.cancel(); + } + } +} From 45e0b9c5fa2262508f4ec2cd8fe08f3b0d73268f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 13:55:23 +0100 Subject: [PATCH 03/13] animator implementation in the LocationLayer --- .../plugins/locationlayer/LocationLayer.java | 169 +++++++++++------- .../locationlayer/LocationLayerConstants.java | 6 +- .../locationlayer/LocationLayerPlugin.java | 6 +- .../locationlayer/RenderModeManager.java | 43 ----- 4 files changed, 110 insertions(+), 114 deletions(-) delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/RenderModeManager.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 3531069e7..b383176da 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -37,7 +37,6 @@ import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.FOREGROUND_LAYER; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.FOREGROUND_STALE_ICON; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.LOCATION_SOURCE; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.NAVIGATION_LAYER; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.SHADOW_ICON; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.SHADOW_LAYER; import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.generateShadow; @@ -63,9 +62,11 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility; -final class LocationLayer { +final class LocationLayer implements LocationLayerAnimator.OnAnimationsValuesChangeListener { + + @RenderMode.Mode + private int renderMode; - private RenderModeManager renderModeManager; private final MapboxMap mapboxMap; private float elevation; @@ -73,15 +74,11 @@ final class LocationLayer { private final Map sourceMap = new HashMap<>(); LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) { - this.renderModeManager = new RenderModeManager(this); this.mapboxMap = mapboxMap; addLocationSource(); addLayers(); applyStyle(mapView.getContext(), options, false); - } - - void updateRenderMode(@RenderMode.Mode int renderMode) { - renderModeManager.updateMode(renderMode); + setRenderMode(RenderMode.NORMAL); } void applyStyle(@NonNull Context context, @NonNull LocationLayerOptions options, boolean isStale) { @@ -101,33 +98,86 @@ void applyStyle(@NonNull Context context, @NonNull LocationLayerOptions options, styleAccuracy(options.accuracyAlpha(), options.accuracyColor()); } + void setRenderMode(@RenderMode.Mode int renderMode) { + this.renderMode = renderMode; + hide(); + + switch (renderMode) { + case RenderMode.NORMAL: + setLayerVisibility(FOREGROUND_LAYER, true); + setLayerVisibility(BACKGROUND_LAYER, true); + setLayerVisibility(ACCURACY_LAYER, true); + break; + case RenderMode.COMPASS: + setLayerVisibility(FOREGROUND_LAYER, true); + setLayerVisibility(BACKGROUND_LAYER, true); + setLayerVisibility(ACCURACY_LAYER, true); + setLayerVisibility(BEARING_LAYER, true); + break; + case RenderMode.GPS: + setLayerVisibility(FOREGROUND_LAYER, true); + setLayerVisibility(BACKGROUND_LAYER, true); + break; + default: + break; + } + } + + int getRenderMode() { + return renderMode; + } + // // Layer action // void show() { - updateLayerVisibility(VISIBLE); + setLayersVisibility(VISIBLE); } void hide() { - updateLayerVisibility(NONE); + setLayersVisibility(NONE); } void setLayerVisibility(String layerId, boolean visible) { layerMap.get(layerId).setProperties(visibility(visible ? VISIBLE : NONE)); } - void setLayerBearing(String layerId, float bearing) { - layerMap.get(layerId).setProperties(iconRotate(bearing)); + private void setLayersVisibility(String visibility) { + for (Layer layer : layerMap.values()) { + layer.setProperties(visibility(visibility)); + } } - void updateAccuracyRadius(Location location) { - CircleLayer accuracyLayer = (CircleLayer) mapboxMap.getLayer(ACCURACY_LAYER); - if (accuracyLayer != null && accuracyLayer.getVisibility().isValue()) { - accuracyLayer.setProperties( - circleRadius(calculateZoomLevelRadius(location)) - ); - } + private void addLayers() { + addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER); + addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER); + addSymbolLayer(FOREGROUND_LAYER, null); + addSymbolLayer(LocationLayerConstants.BEARING_LAYER, null); + addAccuracyLayer(); + } + + private void addSymbolLayer(String layerId, String beforeLayerId) { + SymbolLayer layer = new SymbolLayer(layerId, LOCATION_SOURCE); + layer.setProperties( + iconAllowOverlap(true), + iconIgnorePlacement(true), + iconSize(zoom( + exponential( + stop(22f, iconSize(1f)), + stop(12f, iconSize(1f)), + stop(10f, iconSize(0.6f)), + stop(0f, iconSize(0.6f)) + ).withBase(1f) + )), + iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); + addLayerToMap(layer, beforeLayerId); + } + + private void addAccuracyLayer() { + CircleLayer locationAccuracyLayer = new CircleLayer(ACCURACY_LAYER, LOCATION_SOURCE) + .withProperties(circleRadius(0f)); + addLayerToMap(locationAccuracyLayer, BACKGROUND_LAYER); } private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) { @@ -139,10 +189,17 @@ private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) { layerMap.put(layer.getId(), layer); } - private void addAccuracyLayer() { - CircleLayer locationAccuracyLayer = new CircleLayer(ACCURACY_LAYER, LOCATION_SOURCE) - .withProperties(circleRadius(0f)); - addLayerToMap(locationAccuracyLayer, BACKGROUND_LAYER); + void setLayerBearing(String layerId, float bearing) { + layerMap.get(layerId).setProperties(iconRotate(bearing)); + } + + void updateAccuracyRadius(Location location) { + CircleLayer accuracyLayer = (CircleLayer) mapboxMap.getLayer(ACCURACY_LAYER); + if (accuracyLayer != null && accuracyLayer.getVisibility().isValue()) { + accuracyLayer.setProperties( + circleRadius(calculateZoomLevelRadius(location)) + ); + } } private float calculateZoomLevelRadius(Location location) { @@ -158,10 +215,6 @@ private float calculateZoomLevelRadius(Location location) { // Source actions // - void setLocationPoint(Point locationPoint) { - sourceMap.get(LOCATION_SOURCE).setGeoJson(locationPoint); - } - private void addLocationSource() { FeatureCollection emptyFeature = FeatureCollection.fromFeatures(new Feature[] {}); GeoJsonSource locationSource = new GeoJsonSource( @@ -172,35 +225,8 @@ private void addLocationSource() { sourceMap.put(LOCATION_SOURCE, locationSource); } - private void addLayers() { - addSymbolLayerToMap(SHADOW_LAYER, BACKGROUND_LAYER); - addSymbolLayerToMap(BACKGROUND_LAYER, FOREGROUND_LAYER); - addSymbolLayerToMap(FOREGROUND_LAYER, null); - addSymbolLayerToMap(LocationLayerConstants.BEARING_LAYER, null); - addAccuracyLayer(); - } - - private void updateLayerVisibility(String visibility) { - for (Layer layer : layerMap.values()) { - layer.setProperties(visibility(visibility)); - } - } - - private void addSymbolLayerToMap(String layerId, String beforeLayerId) { - SymbolLayer layer = new SymbolLayer(layerId, LOCATION_SOURCE); - layer.setProperties( - iconAllowOverlap(true), - iconIgnorePlacement(true), - iconSize(zoom( - exponential( - stop(22f, iconSize(1f)), - stop(12f, iconSize(1f)), - stop(10f, iconSize(0.6f)), - stop(0f, iconSize(0.6f)) - ).withBase(1f) - )), - iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); - addLayerToMap(layer, beforeLayerId); + void setLocationPoint(Point locationPoint) { + sourceMap.get(LOCATION_SOURCE).setGeoJson(locationPoint); } // @@ -251,12 +277,7 @@ void updateForegroundOffset(double tilt) { iconOffset(new Float[] {0f, (float) (0.05 * tilt)})); } - void updateForegroundBearing(float bearing) { - layerMap.get(FOREGROUND_LAYER).setProperties(iconRotate(bearing)); - layerMap.get(SHADOW_LAYER).setProperties(iconRotate(bearing)); - } - - void locationsStale(boolean stale) { + void setLocationsStale(boolean stale) { layerMap.get(FOREGROUND_LAYER).setProperties(iconImage(stale ? FOREGROUND_STALE_ICON : FOREGROUND_ICON)); layerMap.get(BACKGROUND_LAYER).setProperties(iconImage(stale ? BACKGROUND_STALE_ICON : BACKGROUND_ICON)); layerMap.get(ACCURACY_LAYER).setProperties(visibility(stale ? NONE : VISIBLE)); @@ -271,9 +292,29 @@ boolean onMapClick(LatLng point) { List features = mapboxMap.queryRenderedFeatures(screenLoc, BACKGROUND_LAYER, FOREGROUND_LAYER, - BEARING_LAYER, - NAVIGATION_LAYER + BEARING_LAYER ); return !features.isEmpty(); } + + @Override + public void onNewLatLngValue(LatLng latLng) { + Point point = Point.fromCoordinates(new double[] {latLng.getLongitude(), latLng.getLatitude()}); + setLocationPoint(point); + } + + @Override + public void onNewGpsBearingValue(float gpsBearing) { + if (renderMode == RenderMode.GPS) { + setLayerBearing(LocationLayerConstants.FOREGROUND_LAYER, gpsBearing); + setLayerBearing(LocationLayerConstants.BACKGROUND_LAYER, gpsBearing); + } + } + + @Override + public void onNewCompassBearingValue(float compassBearing) { + if (renderMode == RenderMode.COMPASS) { + setLayerBearing(LocationLayerConstants.BEARING_LAYER, compassBearing); + } + } } \ No newline at end of file diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java index 368a3be9c..2eb515d7d 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java @@ -26,16 +26,14 @@ final class LocationLayerConstants { static final String BACKGROUND_LAYER = "mapbox-location-stroke-layer"; static final String ACCURACY_LAYER = "mapbox-location-accuracy-layer"; static final String BEARING_LAYER = "mapbox-location-bearing-layer"; - static final String NAVIGATION_LAYER = "mapbox-location-navigation-layer"; // Icons - static final String SHADOW_ICON = "mapbox-location-shadow-icon"; static final String FOREGROUND_ICON = "mapbox-location-icon"; - static final String BEARING_ICON = "mapbox-location-bearing-icon"; static final String BACKGROUND_ICON = "mapbox-location-stroke-icon"; - static final String PUCK_ICON = "mapbox-location-puck-icon"; static final String FOREGROUND_STALE_ICON = "mapbox-location-stale-icon"; static final String BACKGROUND_STALE_ICON = "mapbox-location-background-stale-icon"; + static final String SHADOW_ICON = "mapbox-location-shadow-icon"; + static final String BEARING_ICON = "mapbox-location-bearing-icon"; private LocationLayerConstants() { // Class should not be initialized diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 5231c81f9..4acde8cd3 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -114,7 +114,7 @@ private void initialize() { mapView.addOnMapChangedListener(this); mapboxMap.addOnMapClickListener(this); - locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable); + locationLayer = new LocationLayer(mapView, mapboxMap, options); compassManager = new CompassManager(mapView.getContext()); compassManager.addCompassListener(this); staleStateRunnable = new StaleStateRunnable(this, options.staleStateDelay()); @@ -191,7 +191,7 @@ public void onMapChanged(int change) { @Override public void onStaleStateChange(boolean isStale) { Timber.v("onStaleStateChange: %b", isStale); - locationLayer.locationsStale(isStale); + locationLayer.setLocationsStale(isStale); for (OnLocationStaleListener listener : onLocationStaleListeners) { listener.onStaleStateChange(isStale); @@ -209,7 +209,7 @@ public void applyStyle(@StyleRes int styleRes) { } public void applyStyle(LocationLayerOptions options) { - locationLayer.applyStyle(options); + locationLayer.applyStyle(mapView.getContext(), options, staleStateRunnable.isStale()); if (!options.enableStaleState()) { staleStateRunnable.onStop(); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/RenderModeManager.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/RenderModeManager.java deleted file mode 100644 index 75c9bc53e..000000000 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/RenderModeManager.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer; - -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; - -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_LAYER; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.BACKGROUND_LAYER; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.BEARING_LAYER; -import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.FOREGROUND_LAYER; - -class RenderModeManager { - - private LocationLayer locationLayer; - - RenderModeManager(LocationLayer locationLayer) { - this.locationLayer = locationLayer; - } - - void updateMode(@RenderMode.Mode int renderMode) { - locationLayer.hide(); - - switch (renderMode) { - case RenderMode.NORMAL: - locationLayer.setLayerVisibility(FOREGROUND_LAYER, true); - locationLayer.setLayerVisibility(BACKGROUND_LAYER, true); - locationLayer.setLayerVisibility(ACCURACY_LAYER, true); - break; - case RenderMode.COMPASS: - locationLayer.setLayerVisibility(FOREGROUND_LAYER, true); - locationLayer.setLayerVisibility(BACKGROUND_LAYER, true); - locationLayer.setLayerVisibility(ACCURACY_LAYER, true); - locationLayer.setLayerVisibility(BEARING_LAYER, true); - break; - case RenderMode.GPS: - locationLayer.setLayerVisibility(FOREGROUND_LAYER, true); - locationLayer.setLayerVisibility(BACKGROUND_LAYER, true); - break; - default: - break; - } - } -} - - From b704750d9dbc77812b39d47dbffa250268702091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 14:34:48 +0100 Subject: [PATCH 04/13] reworked location layer camera --- .../locationlayer/LocationLayerAnimator.java | 14 ++- .../locationlayer/LocationLayerCamera.java | 68 +++++++++++ .../locationlayer/camera/BearingAnimator.java | 5 +- .../camera/CameraModeManager.java | 49 -------- .../locationlayer/camera/LatLngAnimator.java | 10 +- .../camera/LocationLayerCamera.java | 106 ------------------ 6 files changed, 82 insertions(+), 170 deletions(-) create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/CameraModeManager.java delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java index ef3934e95..807eae59e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java @@ -12,6 +12,7 @@ import java.util.List; final class LocationLayerAnimator { + private final List listeners = new ArrayList<>(); private LatLngAnimator latLngAnimator; private BearingAnimator gpsBearingAnimator; @@ -25,11 +26,12 @@ void removeListener(OnAnimationsValuesChangeListener listener) { listeners.remove(listener); } - void feedNewLocation(@NonNull Location location) { + void feedNewLocation(@NonNull Location previousLocation, @NonNull Location newLocation) { cancelLocationAnimations(); - LatLng latLng = new LatLng(location); - latLngAnimator = new LatLngAnimator(latLng, 1000); - gpsBearingAnimator = new BearingAnimator(location.getBearing(), 1000); + LatLng previousLatLng = new LatLng(previousLocation); + LatLng newLatLng = new LatLng(newLocation); + latLngAnimator = new LatLngAnimator(previousLatLng, newLatLng, 1000); + gpsBearingAnimator = new BearingAnimator(previousLocation.getBearing(), newLocation.getBearing(), 1000); // FIXME: 22/02/2018 evaluate duration of animation better latLngAnimator.addUpdateListener(latLngUpdateListener); @@ -39,9 +41,9 @@ void feedNewLocation(@NonNull Location location) { gpsBearingAnimator.start(); } - void feedNewCompassBearing(float compassBearing) { + void feedNewCompassBearing(float previousCompassBearing, float targetCompassBearing) { cancelCompassAnimations(); - compassBearingAnimator = new BearingAnimator(compassBearing, 1000); + compassBearingAnimator = new BearingAnimator(previousCompassBearing, targetCompassBearing, 1000); // FIXME: 22/02/2018 evaluate duration of animation better compassBearingAnimator.addUpdateListener(compassBearingUpdateListener); diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java new file mode 100644 index 000000000..373e1cae0 --- /dev/null +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -0,0 +1,68 @@ +package com.mapbox.mapboxsdk.plugins.locationlayer; + +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; + +public class LocationLayerCamera implements LocationLayerAnimator.OnAnimationsValuesChangeListener { + + @CameraMode.Mode + private int cameraMode; + + private MapboxMap mapboxMap; + + public LocationLayerCamera(MapboxMap mapboxMap) { + this.mapboxMap = mapboxMap; + } + + public void setCameraMode(@CameraMode.Mode int cameraMode) { + this.cameraMode = cameraMode; + } + + public int getCameraMode() { + return cameraMode; + } + + private void setBearing(float bearing) { + mapboxMap.setBearing(bearing); + } + + private void setLatLng(LatLng latLng) { + mapboxMap.setLatLng(latLng); + } + + @Override + public void onNewLatLngValue(LatLng latLng) { + if (cameraMode == CameraMode.TRACKING + || cameraMode == CameraMode.TRACKING_COMPASS + || cameraMode == CameraMode.TRACKING_GPS + || cameraMode == CameraMode.TRACKING_GPS_NORTH) { + setLatLng(latLng); + } + } + + @Override + public void onNewGpsBearingValue(float gpsBearing) { + if (cameraMode == CameraMode.TRACKING_GPS + || cameraMode == CameraMode.NONE_GPS) { + setBearing(gpsBearing); + } + + if (cameraMode == CameraMode.TRACKING_GPS_NORTH) { + setBearing(0); + } + } + + @Override + public void onNewCompassBearingValue(float compassBearing) { + if (cameraMode == CameraMode.TRACKING_COMPASS + || cameraMode == CameraMode.NONE_COMPASS) { + setBearing(compassBearing); + } + } +} + + +/* + + float targetBearing = Utils.shortestRotation(0, (float) bearing);*/ diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java index 3077d66fd..fbad42dff 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java @@ -7,10 +7,11 @@ public class BearingAnimator extends ValueAnimator { private float targetBearing; - public BearingAnimator(double targetBearing, long duration) { + public BearingAnimator(float previous, float target, long duration) { setEvaluator(new FloatEvaluator()); setDuration(duration); - this.targetBearing = (float) targetBearing; + setFloatValues(previous, target); + this.targetBearing = target; } public float getTargetBearing() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/CameraModeManager.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/CameraModeManager.java deleted file mode 100644 index 620a4a92d..000000000 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/CameraModeManager.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer.camera; - -import android.location.Location; - -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; - -class CameraModeManager { - - private LocationLayerCamera camera; - private int cameraMode; - - CameraModeManager(LocationLayerCamera camera) { - this.camera = camera; - } - - void setCameraMode(@CameraMode.Mode int cameraMode) { - this.cameraMode = cameraMode; - } - - void updateFromBearing(float bearing) { - switch (cameraMode) { - case CameraMode.NONE_COMPASS: - case CameraMode.TRACKING_COMPASS: - camera.buildBearingAnimation(bearing); - break; - default: - break; - } - } - - void updateFromLocation(Location location) { - switch (cameraMode) { - case CameraMode.NONE_GPS: - camera.buildBearingGPSAnimation(location); - break; - case CameraMode.TRACKING: - camera.buildTrackingAnimation(location); - break; - case CameraMode.TRACKING_GPS: - camera.buildTrackingGPSAnimation(location); - break; - case CameraMode.TRACKING_GPS_NORTH: - camera.buildTrackingGPSNorthAnimation(location); - break; - default: - break; - } - } -} diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java index a0838ca21..756a0df9e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java @@ -10,15 +10,11 @@ public class LatLngAnimator extends ValueAnimator { private LatLng target; - public LatLngAnimator(@NonNull LatLng target, long duration) { + public LatLngAnimator(@NonNull LatLng previous, @NonNull LatLng target, long duration) { setDuration(duration); - this.target = target; - } - - @Override - public void setObjectValues(Object... values) { - super.setObjectValues(values); setEvaluator(new LatLngEvaluator()); + setObjectValues(previous, target); + this.target = target; } public LatLng getTarget() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java deleted file mode 100644 index 510069ece..000000000 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.mapbox.mapboxsdk.plugins.locationlayer.camera; - -import android.location.Location; -import android.view.animation.LinearInterpolator; - -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.plugins.locationlayer.Utils; -import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; - -public class LocationLayerCamera { - - private MapboxMap mapboxMap; - private CameraModeManager cameraModeManager; - private MapAnimator mapAnimator; - - public LocationLayerCamera(MapboxMap mapboxMap) { - this.mapboxMap = mapboxMap; - cameraModeManager = new CameraModeManager(this); - } - - public void setCameraMode(@CameraMode.Mode int cameraMode) { - cancelRunningAnimator(); - cameraModeManager.setCameraMode(cameraMode); - } - - public void updateFromCompassBearing(float bearing) { - cameraModeManager.updateFromBearing(bearing); - } - - public void updateFromLocation(Location location) { - cameraModeManager.updateFromLocation(location); - } - - void buildBearingAnimation(float bearing) { - MapAnimator.Builder mapAnimation = MapAnimator.builder(mapboxMap); - addBearingAnimator(mapAnimation, bearing); - mapAnimator = mapAnimation.build(); - mapAnimator.playTogether(); - } - - void buildBearingGPSAnimation(Location location) { - if (location.hasBearing()) { - buildBearingAnimation(location.getBearing()); - } - } - - void buildTrackingAnimation(Location location) { - LatLng target = new LatLng(location); - - LatLngAnimator latLngAnimator = new LatLngAnimator(target, 1000); - latLngAnimator.setInterpolator(new LinearInterpolator()); - - MapAnimator.builder(mapboxMap) - .addLatLngAnimator(latLngAnimator) - .build() - .playTogether(); - } - - void buildTrackingGPSAnimation(Location location) { - MapAnimator.Builder mapAnimation = MapAnimator.builder(mapboxMap); - addLatLngAnimator(location, mapAnimation); - - if (!location.hasBearing()) { - mapAnimation.build().playTogether(); - return; - } - - addBearingAnimator(mapAnimation, location.getBearing()); - mapAnimation.build().playTogether(); - } - - void buildTrackingGPSNorthAnimation(Location location) { - MapAnimator.Builder mapAnimation = MapAnimator.builder(mapboxMap); - addLatLngAnimator(location, mapAnimation); - - double bearing = mapboxMap.getCameraPosition().bearing; - if (bearing == 0) { - mapAnimation.build().playTogether(); - return; - } - - float targetBearing = Utils.shortestRotation(0, (float) bearing); - addBearingAnimator(mapAnimation, targetBearing); - mapAnimation.build().playTogether(); - } - - private void cancelRunningAnimator() { - if (mapAnimator != null && mapAnimator.isRunning()) { - mapAnimator.cancel(); - } - } - - private void addLatLngAnimator(Location location, MapAnimator.Builder mapAnimation) { - LatLng target = new LatLng(location); - LatLngAnimator latLngAnimator = new LatLngAnimator(target, 1000); - latLngAnimator.setInterpolator(new LinearInterpolator()); - mapAnimation.addLatLngAnimator(latLngAnimator); - } - - private void addBearingAnimator(MapAnimator.Builder mapAnimation, float targetBearing) { - BearingAnimator bearingAnimator = new BearingAnimator(targetBearing, 1000); - bearingAnimator.setInterpolator(new LinearInterpolator()); - mapAnimation.addBearingAnimator(bearingAnimator); - } -} From f1c10aa840c71d681f44dbcdff47a3439223f216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 15:05:28 +0100 Subject: [PATCH 05/13] added Animator to LocationLayerPlugin --- .../plugins/locationlayer/LocationLayer.java | 12 ++-- .../locationlayer/LocationLayerCamera.java | 1 + .../locationlayer/LocationLayerPlugin.java | 65 ++++++++++++------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index b383176da..85dd1bc8f 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -132,23 +132,19 @@ int getRenderMode() { // void show() { - setLayersVisibility(VISIBLE); + setRenderMode(renderMode); } void hide() { - setLayersVisibility(NONE); + for (Layer layer : layerMap.values()) { + layer.setProperties(visibility(NONE)); + } } void setLayerVisibility(String layerId, boolean visible) { layerMap.get(layerId).setProperties(visibility(visible ? VISIBLE : NONE)); } - private void setLayersVisibility(String visibility) { - for (Layer layer : layerMap.values()) { - layer.setProperties(visibility(visibility)); - } - } - private void addLayers() { addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER); addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER); diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java index 373e1cae0..2b9f6ea22 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java @@ -17,6 +17,7 @@ public LocationLayerCamera(MapboxMap mapboxMap) { public void setCameraMode(@CameraMode.Mode int cameraMode) { this.cameraMode = cameraMode; + mapboxMap.cancelTransitions(); } public int getCameraMode() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index 4acde8cd3..b064999e6 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -18,9 +18,10 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveListener; import com.mapbox.mapboxsdk.maps.MapboxMap.OnMapClickListener; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode; +import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode; import com.mapbox.services.android.telemetry.location.LocationEngine; import com.mapbox.services.android.telemetry.location.LocationEngineListener; -import com.mapbox.services.commons.geojson.Point; import java.util.concurrent.CopyOnWriteArrayList; @@ -56,11 +57,13 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas private final MapboxMap mapboxMap; private final MapView mapView; private LocationLayerOptions options; - private LocationLayer locationLayer; private LocationEngine locationEngine; private CompassManager compassManager; - // TODO: 21/02/2018 references to animator, LL and camera + private LocationLayer locationLayer; + private LocationLayerCamera locationLayerCamera; + + private LocationLayerAnimator locationLayerAnimator; private boolean isEnabled; private StaleStateRunnable staleStateRunnable; @@ -114,11 +117,16 @@ private void initialize() { mapView.addOnMapChangedListener(this); mapboxMap.addOnMapClickListener(this); - locationLayer = new LocationLayer(mapView, mapboxMap, options); compassManager = new CompassManager(mapView.getContext()); compassManager.addCompassListener(this); staleStateRunnable = new StaleStateRunnable(this, options.staleStateDelay()); + locationLayer = new LocationLayer(mapView, mapboxMap, options); + locationLayerCamera = new LocationLayerCamera(mapboxMap); + locationLayerAnimator = new LocationLayerAnimator(); + locationLayerAnimator.addListener(locationLayer); + locationLayerAnimator.addListener(locationLayerCamera); + enableLocationLayerPlugin(); } @@ -138,7 +146,8 @@ private void enableLocationLayerPlugin() { locationEngine.addLocationEngineListener(this); } setLastLocation(); - locationLayer.setLayersVisibility(true); + setLastCompassHeading(); + locationLayer.show(); } private void disableLocationLayerPlugin() { @@ -147,7 +156,7 @@ private void disableLocationLayerPlugin() { if (locationEngine != null) { locationEngine.removeLocationEngineListener(this); } - locationLayer.setLayersVisibility(false); + locationLayer.hide(); } /** @@ -165,9 +174,23 @@ private void disableLocationLayerPlugin() { * @param locationLayerMode one of the modes found in {@link LocationLayerMode} * @since 0.1.0 */ - // TODO: 21/02/2018 set render mode and camera mode + public void setCameraMode(@CameraMode.Mode int cameraMode) { + locationLayerCamera.setCameraMode(cameraMode); + } + + public @CameraMode.Mode + int getCameraMode() { + return locationLayerCamera.getCameraMode(); + } - // TODO: 21/02/2018 return current render mode and camera mode + public void setRenderMode(@RenderMode.Mode int renderMode) { + locationLayer.setRenderMode(renderMode); + } + + public @RenderMode.Mode + int getRenderMode() { + return locationLayer.getRenderMode(); + } /** * Returns the current location mode being used with this plugin. @@ -182,7 +205,7 @@ public LocationLayerOptions getLocationLayerOptions() { @Override public void onMapChanged(int change) { if (change == MapView.WILL_START_LOADING_MAP) { - // TODO: 21/02/2018 stop animations, notify anyone interested + locationLayerAnimator.cancelAllAnimations(); } else if (change == MapView.DID_FINISH_LOADING_STYLE) { mapStyleFinishedLoading(); } @@ -270,7 +293,7 @@ public void onStart() { locationEngine.addLocationEngineListener(this); } setLastLocation(); - // TODO: 21/02/2018 reset modes + setLastCompassHeading(); } if (mapboxMap != null) { mapboxMap.addOnCameraMoveListener(this); @@ -290,7 +313,7 @@ public void onStart() { public void onStop() { staleStateRunnable.onStop(); compassManager.onStop(); - // TODO: 21/02/2018 stop animations + locationLayerAnimator.cancelAllAnimations(); if (locationEngine != null) { locationEngine.removeLocationEngineListener(this); } @@ -409,10 +432,9 @@ public Location getLastKnownLocation() { @SuppressWarnings( {"MissingPermission"}) private void mapStyleFinishedLoading() { // recreate runtime style components - locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable); - // TODO: 21/02/2018 reset state + locationLayer = new LocationLayer(mapView, mapboxMap, options); setLastLocation(); - + setLastCompassHeading(); } @Override @@ -420,7 +442,6 @@ public void onCameraMove() { CameraPosition position = mapboxMap.getCameraPosition(); locationLayer.updateAccuracyRadius(getLastKnownLocation()); locationLayer.updateForegroundOffset(position.tilt); - locationLayer.updateForegroundBearing((float) position.bearing); } /** @@ -435,17 +456,13 @@ private void updateLocation(final Location location) { } staleStateRunnable.updateLatestLocationTime(); - - // Convert the new location to a Point object. - Point newPoint = Point.fromCoordinates(new double[] {location.getLongitude(), - location.getLatitude()}); - - locationLayer.setLocationPoint(newPoint); - - // TODO: 21/02/2018 notify animator class about new location + Location lastLocation = getLastKnownLocation(); + if (lastLocation != null) { + locationLayerAnimator.feedNewLocation(lastLocation, location); + } } private void updateCompassHeading(float heading) { - // TODO: 21/02/2018 notify animator class about new heading + locationLayerAnimator.feedNewCompassBearing(compassManager.getLastHeading(), heading); } } From 8ffc6fd3687aa3c9b1d4186932b80a7b78a4b8ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 15:32:26 +0100 Subject: [PATCH 06/13] adjusted location activities --- .../location/CompassListenerActivity.java | 4 ++-- .../location/LocationLayerMapChangeActivity.java | 2 +- .../location/LocationLayerModesActivity.java | 16 ++++++++-------- .../location/ManualLocationUpdatesActivity.java | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java index c986b0ddd..fee793df4 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/CompassListenerActivity.java @@ -40,7 +40,7 @@ protected void onCreate(Bundle savedInstanceState) { public void onMapReady(final MapboxMap mapboxMap) { LocationEngine locationEngine = new LostLocationEngine(this); locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); - locationLayerPlugin.setLocationLayerMode(RenderMode.COMPASS); + locationLayerPlugin.setRenderMode(RenderMode.COMPASS); locationLayerPlugin.addCompassListener(new CompassListener() { @Override public void onCompassChanged(float userHeading) { @@ -95,7 +95,7 @@ public void onLowMemory() { protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); - locationLayerPlugin.removeCompassListener(); + //locationLayerPlugin.removeCompassListener(); } @Override diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java index 5a72568e6..f66d93558 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerMapChangeActivity.java @@ -52,7 +52,7 @@ public void onMapReady(MapboxMap mapboxMap) { locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationEngine.activate(); locationPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); - locationPlugin.setLocationLayerMode(RenderMode.COMPASS); + locationPlugin.setRenderMode(RenderMode.COMPASS); } @OnClick(R.id.fabStyles) diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java index 6786c4906..473ed3630 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java @@ -213,11 +213,11 @@ private void showModeListDialog() { String selectedMode = modes.get(position); locationModeBtn.setText(selectedMode); if (selectedMode.contentEquals("Normal")) { - locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL); + locationLayerPlugin.setRenderMode(RenderMode.NORMAL); } else if (selectedMode.contentEquals("Compass")) { - locationLayerPlugin.setLocationLayerMode(RenderMode.COMPASS); + locationLayerPlugin.setRenderMode(RenderMode.COMPASS); } else if (selectedMode.contentEquals("GPS")) { - locationLayerPlugin.setLocationLayerMode(RenderMode.GPS); + locationLayerPlugin.setRenderMode(RenderMode.GPS); } listPopup.dismiss(); }); @@ -240,15 +240,15 @@ private void showTrackingListDialog() { String selectedTrackingType = trackingTypes.get(position); locationTrackingBtn.setText(selectedTrackingType); if (selectedTrackingType.contentEquals("None")) { - locationLayerPlugin.setLocationLayerTracking(CameraMode.NONE); + locationLayerPlugin.setCameraMode(CameraMode.NONE); } else if (selectedTrackingType.contentEquals("Tracking")) { - locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING); + locationLayerPlugin.setCameraMode(CameraMode.TRACKING); } else if (selectedTrackingType.contentEquals("Tracking Compass")) { - locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING_COMPASS); + locationLayerPlugin.setCameraMode(CameraMode.TRACKING_COMPASS); } else if (selectedTrackingType.contentEquals("Tracking GPS")) { - locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING_GPS); + locationLayerPlugin.setCameraMode(CameraMode.TRACKING_GPS); } else if (selectedTrackingType.contentEquals("Tracking GPS North")) { - locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING_GPS_NORTH); + locationLayerPlugin.setCameraMode(CameraMode.TRACKING_GPS_NORTH); } listPopup.dismiss(); }); diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java index 61e597507..8bab874b0 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/ManualLocationUpdatesActivity.java @@ -71,7 +71,7 @@ public void onMapReady(MapboxMap mapboxMap) { locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); locationEngine.activate(); locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, null); - locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL); + locationLayerPlugin.setRenderMode(RenderMode.NORMAL); getLifecycle().addObserver(locationLayerPlugin); } From 63c161c14fd1bed312b8ed636d59570975e8e64c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 15:32:44 +0100 Subject: [PATCH 07/13] animator order fix --- .../mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java | 2 +- .../mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java index fbad42dff..7e73b856e 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java @@ -8,8 +8,8 @@ public class BearingAnimator extends ValueAnimator { private float targetBearing; public BearingAnimator(float previous, float target, long duration) { - setEvaluator(new FloatEvaluator()); setDuration(duration); + setEvaluator(new FloatEvaluator()); setFloatValues(previous, target); this.targetBearing = target; } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java index 756a0df9e..829c71121 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java @@ -12,8 +12,8 @@ public class LatLngAnimator extends ValueAnimator { public LatLngAnimator(@NonNull LatLng previous, @NonNull LatLng target, long duration) { setDuration(duration); - setEvaluator(new LatLngEvaluator()); setObjectValues(previous, target); + setEvaluator(new LatLngEvaluator()); this.target = target; } From 554492ccf3769521987ab9b1640620f9041a94bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 16:25:37 +0100 Subject: [PATCH 08/13] last values ordering fix --- .../plugins/locationlayer/CompassManager.java | 2 +- .../plugins/locationlayer/LocationLayerPlugin.java | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java index 39b59026a..1de842507 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/CompassManager.java @@ -166,10 +166,10 @@ private void updateOrientation(float[] rotationVector) { } private void notifyCompassChangeListeners(float heading) { - lastHeading = heading; for (CompassListener compassListener : compassListeners) { compassListener.onCompassChanged(heading); } + lastHeading = heading; } int getLastAccuracy() { diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index b064999e6..2c691e119 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -64,6 +64,7 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas private LocationLayerCamera locationLayerCamera; private LocationLayerAnimator locationLayerAnimator; + private Location lastLocation; private boolean isEnabled; private StaleStateRunnable staleStateRunnable; @@ -178,8 +179,8 @@ public void setCameraMode(@CameraMode.Mode int cameraMode) { locationLayerCamera.setCameraMode(cameraMode); } - public @CameraMode.Mode - int getCameraMode() { + @CameraMode.Mode + public int getCameraMode() { return locationLayerCamera.getCameraMode(); } @@ -187,8 +188,8 @@ public void setRenderMode(@RenderMode.Mode int renderMode) { locationLayer.setRenderMode(renderMode); } - public @RenderMode.Mode - int getRenderMode() { + @RenderMode.Mode + public int getRenderMode() { return locationLayer.getRenderMode(); } @@ -456,10 +457,11 @@ private void updateLocation(final Location location) { } staleStateRunnable.updateLatestLocationTime(); - Location lastLocation = getLastKnownLocation(); if (lastLocation != null) { locationLayerAnimator.feedNewLocation(lastLocation, location); } + + lastLocation = location; } private void updateCompassHeading(float heading) { From 28fbdd4a4c7b1659501023e72a799025ff8a590f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 16:34:21 +0100 Subject: [PATCH 09/13] string fixes --- app/src/main/res/layout/activity_location_layer_mode.xml | 4 ++-- app/src/main/res/values/strings.xml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/activity_location_layer_mode.xml b/app/src/main/res/layout/activity_location_layer_mode.xml index 9217f2654..3266fae4e 100644 --- a/app/src/main/res/layout/activity_location_layer_mode.xml +++ b/app/src/main/res/layout/activity_location_layer_mode.xml @@ -50,7 +50,7 @@ android:layout_height="wrap_content" android:layout_weight="1.25" android:gravity="center" - android:text="@string/button_location_mode_none" + android:text="@string/button_location_mode_normal" android:textColor="@android:color/white"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 44724899a..40e1e7fa8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -43,6 +43,7 @@ None + Normal Tracking Compass Nav From 9e0f9036dacb8976cbaefdf300df027e577d0a39 Mon Sep 17 00:00:00 2001 From: danesfeder Date: Thu, 22 Feb 2018 16:48:24 +0100 Subject: [PATCH 10/13] Fix GPS layer --- .../plugins/locationlayer/LocationLayer.java | 71 ++++++++++++------- .../locationlayer/LocationLayerOptions.java | 8 +-- .../locationlayer/LocationLayerPlugin.java | 3 +- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 85dd1bc8f..0bba20dc1 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -66,29 +66,27 @@ final class LocationLayer implements LocationLayerAnimator.OnAnimationsValuesCha @RenderMode.Mode private int renderMode; + private boolean isStale; private final MapboxMap mapboxMap; - private float elevation; + private LocationLayerOptions options; + private Context context; private final Map layerMap = new HashMap<>(); private final Map sourceMap = new HashMap<>(); LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) { this.mapboxMap = mapboxMap; + this.context = mapView.getContext(); addLocationSource(); addLayers(); - applyStyle(mapView.getContext(), options, false); + applyStyle(options); setRenderMode(RenderMode.NORMAL); } - void applyStyle(@NonNull Context context, @NonNull LocationLayerOptions options, boolean isStale) { - elevation = options.elevation(); - styleShadow(ContextCompat.getDrawable(context, R.drawable.mapbox_user_icon_shadow)); - - styleForeground( - getDrawable(context, options.foregroundDrawable(), options.foregroundTintColor()), - getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor()), - isStale); + void applyStyle(@NonNull LocationLayerOptions options) { + this.options = options; + styleForeground(options, isStale); styleBackground( getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()), getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()), @@ -96,6 +94,7 @@ void applyStyle(@NonNull Context context, @NonNull LocationLayerOptions options, styleBearing( getDrawable(context, options.bearingDrawable(), options.bearingTintColor())); styleAccuracy(options.accuracyAlpha(), options.accuracyColor()); + styleShadow(ContextCompat.getDrawable(context, R.drawable.mapbox_user_icon_shadow)); } void setRenderMode(@RenderMode.Mode int renderMode) { @@ -104,17 +103,20 @@ void setRenderMode(@RenderMode.Mode int renderMode) { switch (renderMode) { case RenderMode.NORMAL: + styleForeground(options, isStale); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); setLayerVisibility(ACCURACY_LAYER, true); break; case RenderMode.COMPASS: + styleForeground(options, isStale); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); setLayerVisibility(ACCURACY_LAYER, true); setLayerVisibility(BEARING_LAYER, true); break; case RenderMode.GPS: + styleForeground(options, isStale); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); break; @@ -237,20 +239,10 @@ private void styleBackground(Drawable backgroundDrawable, Drawable backgroundDra } private void styleShadow(Drawable shadowDrawable) { - mapboxMap.addImage(SHADOW_ICON, generateShadow(shadowDrawable, elevation)); + mapboxMap.addImage(SHADOW_ICON, generateShadow(shadowDrawable, options.elevation())); layerMap.get(SHADOW_LAYER).setProperties(iconImage(SHADOW_ICON)); } - private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale, boolean isStale) { - mapboxMap.addImage(FOREGROUND_ICON, getBitmapFromDrawable(foregroundDrawable)); - mapboxMap.addImage(FOREGROUND_STALE_ICON, getBitmapFromDrawable(foregroundDrawableStale)); - - layerMap.get(FOREGROUND_LAYER).setProperties( - iconImage(isStale - ? FOREGROUND_STALE_ICON : FOREGROUND_ICON), - iconRotate(90f)); - } - private void styleBearing(Drawable bearingDrawable) { mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable)); layerMap.get(BEARING_LAYER).setProperties( @@ -266,6 +258,34 @@ private void styleAccuracy(float accuracyAlpha, @ColorInt int accuracyColor) { ); } + private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale, boolean isStale) { + mapboxMap.addImage(FOREGROUND_ICON, getBitmapFromDrawable(foregroundDrawable)); + mapboxMap.addImage(FOREGROUND_STALE_ICON, getBitmapFromDrawable(foregroundDrawableStale)); + + layerMap.get(FOREGROUND_LAYER).setProperties( + iconImage(isStale + ? FOREGROUND_STALE_ICON : FOREGROUND_ICON), + iconRotate(90f)); + } + + private void styleForeground(@NonNull LocationLayerOptions options, boolean isStale) { + if (renderMode == RenderMode.GPS) { + styleForegroundGPS(isStale); + } else { + styleForeground( + getDrawable(context, options.foregroundDrawable(), options.foregroundTintColor()), + getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor()), + isStale); + } + } + + private void styleForegroundGPS(boolean isStale) { + styleForeground( + getDrawable(context, options.gpsDrawable(), options.foregroundTintColor()), + getDrawable(context, options.gpsDrawable(), options.foregroundStaleTintColor()), + isStale); + } + void updateForegroundOffset(double tilt) { layerMap.get(FOREGROUND_LAYER).setProperties( iconOffset(new Float[] {0f, (float) (-0.05 * tilt)})); @@ -273,10 +293,11 @@ void updateForegroundOffset(double tilt) { iconOffset(new Float[] {0f, (float) (0.05 * tilt)})); } - void setLocationsStale(boolean stale) { - layerMap.get(FOREGROUND_LAYER).setProperties(iconImage(stale ? FOREGROUND_STALE_ICON : FOREGROUND_ICON)); - layerMap.get(BACKGROUND_LAYER).setProperties(iconImage(stale ? BACKGROUND_STALE_ICON : BACKGROUND_ICON)); - layerMap.get(ACCURACY_LAYER).setProperties(visibility(stale ? NONE : VISIBLE)); + void setLocationsStale(boolean isStale) { + this.isStale = isStale; + layerMap.get(FOREGROUND_LAYER).setProperties(iconImage(isStale ? FOREGROUND_STALE_ICON : FOREGROUND_ICON)); + layerMap.get(BACKGROUND_LAYER).setProperties(iconImage(isStale ? BACKGROUND_STALE_ICON : BACKGROUND_ICON)); + layerMap.get(ACCURACY_LAYER).setProperties(visibility(isStale ? NONE : VISIBLE)); } // diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java index 74e0b74a1..9c554159f 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerOptions.java @@ -104,7 +104,7 @@ public static LocationLayerOptions createFromAttributes(@NonNull Context context builder.staleStateDelay(typedArray.getInteger( R.styleable.LocationLayer_staleStateDelay, (int) STALE_STATE_DELAY_MS)); } - builder.navigationDrawable(typedArray.getResourceId( + builder.gpsDrawable(typedArray.getResourceId( R.styleable.LocationLayer_navigationDrawable, -1)); float elevation = typedArray.getDimension( R.styleable.LocationLayer_elevation, 0); @@ -199,7 +199,7 @@ private static Builder builder() { * @since 0.4.0 */ @DrawableRes - public abstract int navigationDrawable(); + public abstract int gpsDrawable(); /** * Supply a Drawable that is to be rendered on top of all of the content in the Location Layer @@ -391,12 +391,12 @@ public abstract static class Builder { /** * Defines the drawable used for the navigation state icon. * - * @param navigationDrawable the drawable resource ID + * @param gpsDrawable the drawable resource ID * @return this builder for chaining options together * @attr ref R.styleable#LocationLayer_navigationDrawable * @since 0.4.0 */ - public abstract Builder navigationDrawable(@DrawableRes int navigationDrawable); + public abstract Builder gpsDrawable(@DrawableRes int gpsDrawable); /** * Supply a Drawable that is to be rendered on top of all of the content in the Location Layer diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java index b064999e6..ff84cab07 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPlugin.java @@ -213,7 +213,6 @@ public void onMapChanged(int change) { @Override public void onStaleStateChange(boolean isStale) { - Timber.v("onStaleStateChange: %b", isStale); locationLayer.setLocationsStale(isStale); for (OnLocationStaleListener listener : onLocationStaleListeners) { @@ -232,7 +231,7 @@ public void applyStyle(@StyleRes int styleRes) { } public void applyStyle(LocationLayerOptions options) { - locationLayer.applyStyle(mapView.getContext(), options, staleStateRunnable.isStale()); + locationLayer.applyStyle(options); if (!options.enableStaleState()) { staleStateRunnable.onStop(); } From f7490bd5e8c5aa73f40aa9a239deaaa32713ec7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 16:50:25 +0100 Subject: [PATCH 11/13] using previous animated value when starting a new one --- .../locationlayer/LocationLayerAnimator.java | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java index 807eae59e..f94d6c62b 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java @@ -27,11 +27,24 @@ void removeListener(OnAnimationsValuesChangeListener listener) { } void feedNewLocation(@NonNull Location previousLocation, @NonNull Location newLocation) { - cancelLocationAnimations(); - LatLng previousLatLng = new LatLng(previousLocation); + LatLng previousLatLng; + if (latLngAnimator != null) { + previousLatLng = (LatLng) latLngAnimator.getAnimatedValue(); + } else { + previousLatLng = new LatLng(previousLocation); + } LatLng newLatLng = new LatLng(newLocation); + + float previousBearing; + if (gpsBearingAnimator != null) { + previousBearing = (float) gpsBearingAnimator.getAnimatedValue(); + } else { + previousBearing = previousLocation.getBearing(); + } + + cancelLocationAnimations(); latLngAnimator = new LatLngAnimator(previousLatLng, newLatLng, 1000); - gpsBearingAnimator = new BearingAnimator(previousLocation.getBearing(), newLocation.getBearing(), 1000); + gpsBearingAnimator = new BearingAnimator(previousBearing, newLocation.getBearing(), 1000); // FIXME: 22/02/2018 evaluate duration of animation better latLngAnimator.addUpdateListener(latLngUpdateListener); @@ -93,16 +106,19 @@ void cancelAllAnimations() { private void cancelLocationAnimations() { if (latLngAnimator != null) { latLngAnimator.cancel(); + latLngAnimator.removeAllUpdateListeners(); } if (gpsBearingAnimator != null) { gpsBearingAnimator.cancel(); + gpsBearingAnimator.removeAllUpdateListeners(); } } private void cancelCompassAnimations() { if (compassBearingAnimator != null) { compassBearingAnimator.cancel(); + compassBearingAnimator.removeAllUpdateListeners(); } } } From 7eb8070e2549b7ee772009bb3121b042ab2ed2ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 16:59:16 +0100 Subject: [PATCH 12/13] small tweaks --- .../testapp/activity/location/LocationLayerModesActivity.java | 1 - .../mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java index 473ed3630..dd327d07f 100644 --- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java +++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/location/LocationLayerModesActivity.java @@ -92,7 +92,6 @@ public void onMapReady(MapboxMap mapboxMap) { locationEngine.activate(); locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine); locationLayerPlugin.addOnLocationClickListener(this); - locationLayerPlugin.setLocationLayerEnabled(true); getLifecycle().addObserver(locationLayerPlugin); } diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 0bba20dc1..772813b01 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -192,7 +192,7 @@ void setLayerBearing(String layerId, float bearing) { } void updateAccuracyRadius(Location location) { - CircleLayer accuracyLayer = (CircleLayer) mapboxMap.getLayer(ACCURACY_LAYER); + CircleLayer accuracyLayer = (CircleLayer) layerMap.get(ACCURACY_LAYER); if (accuracyLayer != null && accuracyLayer.getVisibility().isValue()) { accuracyLayer.setProperties( circleRadius(calculateZoomLevelRadius(location)) From c735b7a058f3bb4592b70a7c1e1b7d091b503dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 22 Feb 2018 17:29:01 +0100 Subject: [PATCH 13/13] setting accuracy ring only if using the right mode --- .../mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 772813b01..e58fc52b2 100644 --- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java +++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java @@ -193,7 +193,7 @@ void setLayerBearing(String layerId, float bearing) { void updateAccuracyRadius(Location location) { CircleLayer accuracyLayer = (CircleLayer) layerMap.get(ACCURACY_LAYER); - if (accuracyLayer != null && accuracyLayer.getVisibility().isValue()) { + if (accuracyLayer != null && (renderMode == RenderMode.COMPASS || renderMode == RenderMode.NORMAL)) { accuracyLayer.setProperties( circleRadius(calculateZoomLevelRadius(location)) ); @@ -223,7 +223,7 @@ private void addLocationSource() { sourceMap.put(LOCATION_SOURCE, locationSource); } - void setLocationPoint(Point locationPoint) { + private void setLocationPoint(Point locationPoint) { sourceMap.get(LOCATION_SOURCE).setGeoJson(locationPoint); }