From 6f79da7a82dde7dc529f4cd2217152781f792900 Mon Sep 17 00:00:00 2001
From: danesfeder
Date: Mon, 19 Feb 2018 17:38:57 +0100
Subject: [PATCH 01/24] Add initial animators
---
.../locationlayer/camera/BearingAnimator.java | 19 +++
.../locationlayer/camera/LatLngAnimator.java | 41 +++++
.../locationlayer/camera/MapAnimator.java | 160 ++++++++++++++++++
.../locationlayer/camera/TiltAnimator.java | 19 +++
.../locationlayer/camera/ZoomAnimator.java | 19 +++
5 files changed, 258 insertions(+)
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/TiltAnimator.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/ZoomAnimator.java
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
new file mode 100644
index 000000000..3077d66fd
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/BearingAnimator.java
@@ -0,0 +1,19 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer.camera;
+
+import android.animation.FloatEvaluator;
+import android.animation.ValueAnimator;
+
+public class BearingAnimator extends ValueAnimator {
+
+ private float targetBearing;
+
+ public BearingAnimator(double targetBearing, long duration) {
+ setEvaluator(new FloatEvaluator());
+ setDuration(duration);
+ this.targetBearing = (float) targetBearing;
+ }
+
+ public float getTargetBearing() {
+ return targetBearing;
+ }
+}
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
new file mode 100644
index 000000000..a0838ca21
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LatLngAnimator.java
@@ -0,0 +1,41 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer.camera;
+
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import android.support.annotation.NonNull;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+public class LatLngAnimator extends ValueAnimator {
+
+ private LatLng target;
+
+ public LatLngAnimator(@NonNull LatLng target, long duration) {
+ setDuration(duration);
+ this.target = target;
+ }
+
+ @Override
+ public void setObjectValues(Object... values) {
+ super.setObjectValues(values);
+ setEvaluator(new LatLngEvaluator());
+ }
+
+ public LatLng getTarget() {
+ return target;
+ }
+
+ private static class LatLngEvaluator implements TypeEvaluator {
+
+ private final LatLng latLng = new LatLng();
+
+ @Override
+ public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
+ latLng.setLatitude(startValue.getLatitude()
+ + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
+ latLng.setLongitude(startValue.getLongitude()
+ + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
+ return latLng;
+ }
+ }
+}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java
new file mode 100644
index 000000000..8ebc21292
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java
@@ -0,0 +1,160 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer.camera;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MapAnimator {
+
+ private List animators;
+ private AnimatorSet animatorSet;
+
+ private MapAnimator(List animators) {
+ this.animators = animators;
+ animatorSet = new AnimatorSet();
+ }
+
+ public void playTogether() {
+ animatorSet.playTogether(animators);
+ animatorSet.start();
+ }
+
+ public void playTogether(@Nullable Animator.AnimatorListener listener) {
+ animatorSet.addListener(listener);
+ playTogether();
+ }
+
+ public void playSequentially() {
+ animatorSet.playSequentially(animators);
+ animatorSet.start();
+ }
+
+ public void playSequentially(@Nullable Animator.AnimatorListener listener) {
+ animatorSet.addListener(listener);
+ playSequentially();
+ }
+
+ public void cancel() {
+ animatorSet.cancel();
+ }
+
+ public static Builder builder(MapboxMap mapboxMap) {
+ return new Builder(mapboxMap);
+ }
+
+ public static final class Builder {
+
+ private final MapboxMap mapboxMap;
+ private List animators;
+ private CameraPosition currentPosition;
+
+ private Builder(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ this.animators = new ArrayList<>();
+ // Get the current target from the current map camera position
+ currentPosition = mapboxMap.getCameraPosition();
+ }
+
+ public Builder addLatLngAnimator(@NonNull LatLngAnimator latLngAnimator) {
+
+ LatLng currentTarget = currentPosition.target;
+ if (currentTarget == latLngAnimator.getTarget()) {
+ return this;
+ }
+
+ latLngAnimator.setObjectValues(currentTarget, latLngAnimator.getTarget());
+ latLngAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mapboxMap.setLatLng((LatLng) animation.getAnimatedValue());
+ }
+ });
+
+ animators.add(latLngAnimator);
+ return this;
+ }
+
+ public Builder addZoomAnimator(@NonNull ZoomAnimator zoomAnimator) {
+
+ float currentZoom = (float) currentPosition.zoom;
+ if (currentZoom == zoomAnimator.getTargetZoom()) {
+ return this;
+ }
+
+ zoomAnimator.setFloatValues(currentZoom, zoomAnimator.getTargetZoom());
+ zoomAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mapboxMap.setZoom((Float) animation.getAnimatedValue());
+ }
+ });
+
+ animators.add(zoomAnimator);
+ return this;
+ }
+
+ public Builder addBearingAnimator(@NonNull BearingAnimator bearingAnimator) {
+
+ float currentBearing = (float) currentPosition.bearing;
+ float normalizedTargetBearing = normalizeBearing(currentBearing, bearingAnimator.getTargetBearing());
+ if (currentBearing == normalizedTargetBearing) {
+ return this;
+ }
+
+ bearingAnimator.setFloatValues(currentBearing, normalizedTargetBearing);
+ bearingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mapboxMap.setBearing((Float) animation.getAnimatedValue());
+ }
+ });
+
+ animators.add(bearingAnimator);
+ return this;
+ }
+
+ public Builder addTiltAnimator(@NonNull TiltAnimator tiltAnimator) {
+
+ float currentTilt = (float) currentPosition.tilt;
+ if (currentTilt == tiltAnimator.getTargetTilt()) {
+ return this;
+ }
+
+ tiltAnimator.setFloatValues(currentTilt, tiltAnimator.getTargetTilt());
+ tiltAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mapboxMap.setTilt((Float) animation.getAnimatedValue());
+ }
+ });
+
+ animators.add(tiltAnimator);
+ return this;
+ }
+
+
+
+ public MapAnimator build() {
+ return new MapAnimator(animators);
+ }
+ }
+
+ private static float normalizeBearing(float currentBearing, float targetBearing) {
+ double diff = currentBearing - targetBearing;
+ if (diff > 180.0f) {
+ targetBearing += 360.0f;
+ } else if (diff < -180.0f) {
+ targetBearing -= 360.f;
+ }
+ return targetBearing;
+ }
+}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/TiltAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/TiltAnimator.java
new file mode 100644
index 000000000..216afb148
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/TiltAnimator.java
@@ -0,0 +1,19 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer.camera;
+
+import android.animation.FloatEvaluator;
+import android.animation.ValueAnimator;
+
+public class TiltAnimator extends ValueAnimator {
+
+ private float targetTilt;
+
+ public TiltAnimator(double targetTilt, long duration) {
+ setEvaluator(new FloatEvaluator());
+ setDuration(duration);
+ this.targetTilt = (float) targetTilt;
+ }
+
+ public float getTargetTilt() {
+ return targetTilt;
+ }
+}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/ZoomAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/ZoomAnimator.java
new file mode 100644
index 000000000..34327760e
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/ZoomAnimator.java
@@ -0,0 +1,19 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer.camera;
+
+import android.animation.FloatEvaluator;
+import android.animation.ValueAnimator;
+
+public class ZoomAnimator extends ValueAnimator {
+
+ private float targetZoom;
+
+ public ZoomAnimator(double targetZoom, long duration) {
+ setEvaluator(new FloatEvaluator());
+ setDuration(duration);
+ this.targetZoom = (float) targetZoom;
+ }
+
+ public float getTargetZoom() {
+ return targetZoom;
+ }
+}
From d25dafa144f0e4eef8ab152b4874fb437b80d766 Mon Sep 17 00:00:00 2001
From: Dan Nesfeder
Date: Wed, 21 Feb 2018 15:40:26 +0100
Subject: [PATCH 02/24] Add Camera and Tracking Modes (#294)
* Add style / tracking modes for camera integration
* Fix broken tests
* API tweaks and example update
---
.../locationlayer/LocationLayerTest.java | 20 +--
.../places/autocomplete/data/TestData.java | 2 +-
.../location/CompassListenerActivity.java | 2 +-
.../LocationLayerMapChangeActivity.java | 2 +-
.../location/LocationLayerModesActivity.java | 105 ++++++++++++----
.../ManualLocationUpdatesActivity.java | 2 +-
.../layout/activity_location_layer_mode.xml | 46 ++++---
app/src/main/res/values/strings.xml | 2 +
.../locationlayer/LocationLayerMode.java | 15 +--
.../locationlayer/LocationLayerPlugin.java | 107 ++++++++++------
.../locationlayer/LocationLayerTracking.java | 68 ++++++++++
.../plugins/locationlayer/Utils.java | 4 +-
.../camera/LocationLayerCamera.java | 119 ++++++++++++++++++
13 files changed, 387 insertions(+), 107 deletions(-)
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java
diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
index 4c6e55e45..7698a6b5e 100644
--- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
+++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
@@ -85,7 +85,7 @@ public void locationSourceAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
assertTrue(mapboxMap.getSource(LOCATION_SOURCE) != null);
}
});
@@ -97,7 +97,7 @@ public void locationTrackingLayersAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
assertTrue(mapboxMap.getLayer(ACCURACY_LAYER) != null);
assertTrue(mapboxMap.getLayer(BACKGROUND_LAYER) != null);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
@@ -111,7 +111,7 @@ public void locationBearingLayersAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.COMPASS);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
assertTrue(mapboxMap.getLayer(ACCURACY_LAYER) != null);
assertTrue(mapboxMap.getLayer(BACKGROUND_LAYER) != null);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
@@ -126,7 +126,7 @@ public void locationNavigationLayersAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.COMPASS);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
assertTrue(mapboxMap.getLayer(NAVIGATION_LAYER) != null);
}
});
@@ -138,9 +138,9 @@ public void locationLayerModeCorrectlySetToNone() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.NONE);
+ locationLayerPlugin.setLocationLayerEnabled(false);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER).getVisibility().getValue()
.equals(Property.NONE));
}
@@ -153,11 +153,11 @@ public void onMapChangeLocationLayerRedrawn() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
mapboxMap.setStyleUrl(Style.SATELLITE);
uiController.loopMainThreadForAtLeast(500);
- assertEquals(locationLayerPlugin.getLocationLayerMode(), LocationLayerMode.TRACKING);
+ assertEquals(locationLayerPlugin.getLocationLayerMode(), LocationLayerMode.NORMAL);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER).getVisibility().getValue()
.equals(Property.VISIBLE));
@@ -175,7 +175,7 @@ public void whenStaleTimeSet_iconsDoChangeAtAppropriateTime() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
SymbolLayer symbolLayer = mapboxMap.getLayerAs(FOREGROUND_LAYER);
assert symbolLayer != null;
assertThat(symbolLayer.getIconImage().getValue(), equalTo(FOREGROUND_ICON));
@@ -193,7 +193,7 @@ public void whenDrawableChanged_continuesUsingStaleIcons() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
locationLayerPlugin.applyStyle(LocationLayerOptions.builder(context).staleStateDelay(100).build());
locationLayerPlugin.forceLocationUpdate(location);
uiController.loopMainThreadForAtLeast(200);
diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/places/autocomplete/data/TestData.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/places/autocomplete/data/TestData.java
index ee97f639c..01e923c94 100644
--- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/places/autocomplete/data/TestData.java
+++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/places/autocomplete/data/TestData.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.plugins.places.autocomplete.data;
import com.google.gson.JsonObject;
-import com.mapbox.geocoding.v5.models.CarmenFeature;
+import com.mapbox.api.geocoding.v5.models.CarmenFeature;
import com.mapbox.plugins.places.autocomplete.data.entity.SearchHistoryEntity;
final class TestData {
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 8e4b32c6e..5e94b7622 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.setLocationLayerEnabled(LocationLayerMode.COMPASS);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
locationLayerPlugin.addCompassListener(new CompassListener() {
@Override
public void onCompassChanged(float userHeading) {
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 f1a27f8a8..941a86eef 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.setLocationLayerEnabled(LocationLayerMode.COMPASS);
+ locationPlugin.setLocationLayerMode(LocationLayerMode.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 bd2bb2ad9..598a4db0d 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
@@ -1,12 +1,17 @@
package com.mapbox.mapboxsdk.plugins.testapp.activity.location;
+import android.annotation.SuppressLint;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.ListPopupWindow;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.TextView;
import android.widget.Toast;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
@@ -16,6 +21,7 @@
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerTracking;
import com.mapbox.mapboxsdk.plugins.locationlayer.OnLocationLayerClickListener;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.services.android.location.LostLocationEngine;
@@ -23,6 +29,9 @@
import com.mapbox.services.android.telemetry.location.LocationEngineListener;
import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
+import java.util.ArrayList;
+import java.util.List;
+
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
@@ -32,6 +41,14 @@ public class LocationLayerModesActivity extends AppCompatActivity implements OnM
@BindView(R.id.map_view)
MapView mapView;
+ @BindView(R.id.tv_mode)
+ TextView modeText;
+ @BindView(R.id.tv_tracking)
+ TextView trackingText;
+ @BindView(R.id.button_location_mode)
+ Button locationModeBtn;
+ @BindView(R.id.button_location_tracking)
+ Button locationTrackingBtn;
private LocationLayerPlugin locationLayerPlugin;
private LocationEngine locationEngine;
@@ -49,41 +66,23 @@ protected void onCreate(Bundle savedInstanceState) {
}
@SuppressWarnings( {"MissingPermission"})
- @OnClick(R.id.button_location_mode_none)
- public void locationModeNone(View view) {
+ @OnClick(R.id.button_location_mode)
+ public void locationMode(View view) {
if (locationLayerPlugin == null) {
return;
}
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.NONE);
+ showModeListDialog();
}
- @SuppressWarnings( {"MissingPermission"})
- @OnClick(R.id.button_location_mode_compass)
+ @OnClick(R.id.button_location_tracking)
public void locationModeCompass(View view) {
if (locationLayerPlugin == null) {
return;
}
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.COMPASS);
- }
-
- @SuppressWarnings( {"MissingPermission"})
- @OnClick(R.id.button_location_mode_tracking)
- public void locationModeTracking(View view) {
- if (locationLayerPlugin == null) {
- return;
- }
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.TRACKING);
- }
-
- @SuppressWarnings( {"MissingPermission"})
- @OnClick(R.id.button_location_mode_navigation)
- public void locationModeNavigation(View view) {
- if (locationLayerPlugin == null) {
- return;
- }
- locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.NAVIGATION);
+ showTrackingListDialog();
}
+ @SuppressLint("MissingPermission")
@Override
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
@@ -93,6 +92,7 @@ public void onMapReady(MapboxMap mapboxMap) {
locationEngine.activate();
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
locationLayerPlugin.setOnLocationClickListener(this);
+ locationLayerPlugin.setLocationLayerEnabled(true);
getLifecycle().addObserver(locationLayerPlugin);
}
@@ -191,10 +191,67 @@ public void onConnected() {
public void onLocationChanged(Location location) {
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(), location.getLongitude()), 16));
+ locationEngine.removeLocationEngineListener(this);
}
@Override
public void onLocationLayerClick() {
Toast.makeText(this, "OnLocationLayerClick", Toast.LENGTH_LONG).show();
}
+
+ private void showModeListDialog() {
+ List modes = new ArrayList<>();
+ modes.add("Normal");
+ modes.add("Compass");
+ modes.add("Navigation");
+ ArrayAdapter profileAdapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_list_item_1, modes);
+ ListPopupWindow listPopup = new ListPopupWindow(this);
+ listPopup.setAdapter(profileAdapter);
+ listPopup.setAnchorView(locationModeBtn);
+ listPopup.setOnItemClickListener((parent, itemView, position, id) -> {
+ String selectedMode = modes.get(position);
+ locationModeBtn.setText(selectedMode);
+ if (selectedMode.contentEquals("Normal")) {
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ } else if (selectedMode.contentEquals("Compass")) {
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
+ } else if (selectedMode.contentEquals("Navigation")) {
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NAVIGATION);
+ }
+ listPopup.dismiss();
+ });
+ listPopup.show();
+ }
+
+ private void showTrackingListDialog() {
+ List trackingTypes = new ArrayList<>();
+ trackingTypes.add("None");
+ trackingTypes.add("Tracking");
+ trackingTypes.add("Tracking Compass");
+ trackingTypes.add("Tracking GPS");
+ trackingTypes.add("Tracking GPS North");
+ ArrayAdapter profileAdapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_list_item_1, trackingTypes);
+ ListPopupWindow listPopup = new ListPopupWindow(this);
+ listPopup.setAdapter(profileAdapter);
+ listPopup.setAnchorView(locationTrackingBtn);
+ listPopup.setOnItemClickListener((parent, itemView, position, id) -> {
+ String selectedTrackingType = trackingTypes.get(position);
+ locationTrackingBtn.setText(selectedTrackingType);
+ if (selectedTrackingType.contentEquals("None")) {
+ locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.NONE);
+ } else if (selectedTrackingType.contentEquals("Tracking")) {
+ locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING);
+ } else if (selectedTrackingType.contentEquals("Tracking Compass")) {
+ locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING_COMPASS);
+ } else if (selectedTrackingType.contentEquals("Tracking GPS")) {
+ locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING_GPS);
+ } else if (selectedTrackingType.contentEquals("Tracking GPS North")) {
+ locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING_GPS_NORTH);
+ }
+ listPopup.dismiss();
+ });
+ listPopup.show();
+ }
}
\ No newline at end of file
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 c50fd06b2..874e752f0 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.setLocationLayerEnabled(LocationLayerMode.TRACKING);
+ locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
getLifecycle().addObserver(locationLayerPlugin);
}
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 69fdc4ede..9217f2654 100644
--- a/app/src/main/res/layout/activity_location_layer_mode.xml
+++ b/app/src/main/res/layout/activity_location_layer_mode.xml
@@ -32,40 +32,46 @@
tools:layout_constraintLeft_creator="1"
tools:layout_constraintRight_creator="1">
-
+ android:layout_height="match_parent"
+ android:layout_weight=".75"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:textColor="@color/mapboxWhite"
+ android:gravity="center"
+ android:text="@string/mode"/>
-
+ android:layout_height="match_parent"
+ android:layout_weight=".85"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:textColor="@color/mapboxWhite"
+ android:gravity="center"
+ android:text="@string/tracking"/>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5fda23135..44724899a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -53,4 +53,6 @@
Example shows how to launch the Place Picker using the Floating action button and receiving a result in onActivityResult.
+ Mode:
+ Tracking:
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java
index 3e6f94da3..f8226b2dc 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java
@@ -18,24 +18,17 @@ private LocationLayerMode() {
/**
* One of these constants should be used when
- * {@link LocationLayerPlugin#setLocationLayerEnabled(int)}'s called. The
- * mode can be switched at anytime by calling the {@code setLocationLayerEnabled} method passing
+ * {@link LocationLayerPlugin#setLocationLayerMode(int)}'s called. The
+ * mode can be switched at anytime by calling the {@code setLocationLayerMode} method passing
* in the new mode you'd like the location layer to be in.
*
* @since 0.1.0
*/
- @IntDef( {NONE, COMPASS, NAVIGATION, TRACKING})
+ @IntDef( {COMPASS, NAVIGATION, NORMAL})
@Retention(RetentionPolicy.SOURCE)
@interface Mode {
}
- /**
- * All Tracking, bearing, and location are disabled.
- *
- * @since 0.1.0
- */
- public static final int NONE = 0x00000000;
-
/**
* Tracking the bearing of the user based on sensor data.
*
@@ -55,5 +48,5 @@ private LocationLayerMode() {
*
* @since 0.1.0
*/
- public static final int TRACKING = 0x00000012;
+ public static final int NORMAL = 0x00000012;
}
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 a0515f19b..de1ed3cb0 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
@@ -21,6 +21,7 @@
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;
@@ -40,11 +41,13 @@
* The Location layer plugin provides location awareness to your mobile application. Enabling this
* plugin provides a contextual experience to your users by showing an icon representing the users
* current location. A few different modes are offered to provide the right context to your users at
- * the correct time. {@link LocationLayerMode#TRACKING} simply shows the users location on the map
+ * the correct time. {@link LocationLayerMode#NORMAL} simply shows the users location on the map
* represented as a dot. {@link LocationLayerMode#COMPASS} mode allows you to display an arrow icon
* (by default) that points in the direction the device is pointing in.
* {@link LocationLayerMode#NAVIGATION} can be used in conjunction with our Navigation SDK to
- * display a larger icon we call the user puck. Lastly, {@link LocationLayerMode#NONE} can be used
+ * display a larger icon we call the user puck.
+ *
+ * Lastly, {@link LocationLayerPlugin#setLocationLayerEnabled(boolean)} can be used
* to disable the Location Layer but keep the instance around till the activity is destroyed.
*
* Using this plugin requires you to request permission beforehand manually or using
@@ -61,12 +64,14 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas
private LocationLayer locationLayer;
private CompassManager compassManager;
private LocationEngine locationEngine;
+ private LocationLayerCamera camera;
private final MapboxMap mapboxMap;
private final MapView mapView;
// Enabled booleans
@LocationLayerMode.Mode
private int locationLayerMode;
+ private boolean isEnabled;
// Previous compass and location values
private float previousMagneticHeading;
@@ -128,9 +133,21 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa
private void initialize() {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
staleStateRunnable = new StaleStateRunnable(options.staleStateDelay());
- locationLayerMode = LocationLayerMode.NONE;
+ locationLayerMode = LocationLayerMode.NORMAL;
locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable);
compassManager = new CompassManager(mapView.getContext(), this);
+ camera = new LocationLayerCamera(mapboxMap);
+ enableLocationLayerPlugin();
+ }
+
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
+ public void setLocationLayerEnabled(boolean isEnabled) {
+ this.isEnabled = isEnabled;
+ if (isEnabled) {
+ enableLocationLayerPlugin();
+ } else {
+ disableLocationLayerPlugin();
+ }
}
/**
@@ -140,43 +157,33 @@ private void initialize() {
* to ensure that you have the requested the required user location permissions.
*
*
- *
{@link LocationLayerMode#TRACKING}: Display the user location on the map as a small dot
+ *
{@link LocationLayerMode#NORMAL}: Display the user location on the map as a small dot
*
{@link LocationLayerMode#COMPASS}: Display the user location and current heading/bearing
*
{@link LocationLayerMode#NAVIGATION}: Display the user location on the map using a navigation icon
- *
{@link LocationLayerMode#NONE}: Disable user location showing on the map
*
*
* @param locationLayerMode one of the modes found in {@link LocationLayerMode}
* @since 0.1.0
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
- public void setLocationLayerEnabled(@LocationLayerMode.Mode int locationLayerMode) {
+ public void setLocationLayerMode(@LocationLayerMode.Mode int locationLayerMode) {
this.locationLayerMode = locationLayerMode;
- if (locationLayerMode != LocationLayerMode.NONE) {
- locationLayer.setLayersVisibility(true);
-
- // Set an initial location if one is available and the locationEngines not null
- if (locationEngine != null) {
- setLastLocation();
- locationEngine.addLocationEngineListener(this);
- }
+ 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);
+ }
+ }
- toggleCameraListener();
-
- if (locationLayerMode == LocationLayerMode.COMPASS) {
- setLinearAnimation(false);
- setNavigationEnabled(false);
- setMyBearingEnabled(true);
- } else if (locationLayerMode == LocationLayerMode.NAVIGATION) {
- setMyBearingEnabled(false);
- setNavigationEnabled(true);
- } else if (locationLayerMode == LocationLayerMode.TRACKING) {
- setLinearAnimation(false);
- setMyBearingEnabled(false);
- setNavigationEnabled(false);
- }
- } else {
- disableLocationLayerPlugin();
+ public void setLocationLayerTracking(@LocationLayerTracking.Type int trackingMode) {
+ if (camera != null) {
+ camera.setTrackingMode(trackingMode);
}
}
@@ -236,6 +243,7 @@ public void applyStyle(LocationLayerOptions options) {
*/
public void forceLocationUpdate(@Nullable Location location) {
updateLocation(location);
+ updateCameraLocation(location);
}
/**
@@ -250,7 +258,7 @@ public void forceLocationUpdate(@Nullable Location location) {
public void setLocationEngine(@Nullable LocationEngine locationEngine) {
if (locationEngine != null) {
this.locationEngine = locationEngine;
- setLocationLayerEnabled(locationLayerMode);
+ setLocationLayerMode(locationLayerMode);
} else if (this.locationEngine != null) {
this.locationEngine.removeLocationEngineListener(this);
this.locationEngine = null;
@@ -297,8 +305,8 @@ public void onStop() {
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
- if (locationLayerMode != LocationLayerMode.NONE) {
- setLocationLayerEnabled(locationLayerMode);
+ if (isEnabled) {
+ setLocationLayerMode(locationLayerMode);
}
if (!compassManager.getCompassListeners().isEmpty()
@@ -394,6 +402,7 @@ public void onConnected() {
@Override
public void onLocationChanged(Location location) {
updateLocation(location);
+ updateCameraLocation(location);
}
@Override
@@ -428,6 +437,23 @@ private void updateLocation(Location 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.
*/
@@ -488,8 +514,9 @@ private void mapStyleFinishedLoading() {
// recreate runtime style components
locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable);
// reset state
- setLocationLayerEnabled(locationLayerMode);
+ setLocationLayerMode(locationLayerMode);
setBearing(previousMagneticHeading);
+ updateCameraBearing(previousMagneticHeading);
if (previousPoint != null) {
locationLayer.setLocationPoint(previousPoint);
}
@@ -630,13 +657,21 @@ private void bearingChangeAnimate(float magneticHeading) {
bearingChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
- setBearing((float) valueAnimator.getAnimatedValue());
+ float bearing = (float) valueAnimator.getAnimatedValue();
+ setBearing(bearing);
+ updateCameraBearing(bearing);
}
});
bearingChangeAnimator.start();
previousMagneticHeading = magneticHeading;
}
+ private void updateCameraBearing(float bearing) {
+ if (camera != null) {
+ camera.updateBearing(bearing);
+ }
+ }
+
private void setBearing(float bearing) {
locationLayer.setLayerBearing(
locationLayerMode == LocationLayerMode.NAVIGATION
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java
new file mode 100644
index 000000000..8e9754adf
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java
@@ -0,0 +1,68 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer;
+
+import android.location.Location;
+import android.support.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Contains the variety of Location Layer modes which shape the behavior of the plugin.
+ *
+ * @since 0.1.0
+ */
+public final class LocationLayerTracking {
+
+ private LocationLayerTracking() {
+ // Class should not be initialized
+ }
+
+ /**
+ * Determine the camera tracking behavior in the {@link LocationLayerPlugin}.
+ *
+ * @since 0.4.0
+ */
+ @IntDef( {NONE, TRACKING, TRACKING_COMPASS, TRACKING_GPS, TRACKING_GPS_NORTH})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Type {
+ }
+
+ /**
+ * No camera tracking.
+ *
+ * @since 0.4.0
+ */
+ public static final int NONE = 0x00000000;
+
+ /**
+ * Tracks the user location.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING = 0x0000006;
+
+ /**
+ * Tracks the user location, with camera bearing
+ * based on the bearing provided by the compass.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING_COMPASS = 0x00000010;
+
+ /**
+ * Tracks the user location, with camera bearing
+ * based on the bearing provided by a normalized {@link Location#getBearing()}.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING_GPS = 0x00000014;
+
+
+ /**
+ * Tracks the user location, with camera bearing
+ * always set to north.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING_GPS_NORTH = 0x00000018;
+}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java
index c20d88ab2..851de6375 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/Utils.java
@@ -15,7 +15,7 @@
import com.mapbox.services.commons.geojson.Point;
-final class Utils {
+public final class Utils {
private Utils() {
// Class should not be initialized
@@ -29,7 +29,7 @@ private Utils() {
* @return the shortest degree of rotation possible
* @since 0.4.0
*/
- static float shortestRotation(float magneticHeading, float previousMagneticHeading) {
+ public static float shortestRotation(float magneticHeading, float previousMagneticHeading) {
double diff = previousMagneticHeading - magneticHeading;
if (diff > 180.0f) {
magneticHeading += 360.0f;
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
new file mode 100644
index 000000000..88d6e9d2e
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java
@@ -0,0 +1,119 @@
+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.LocationLayerTracking;
+import com.mapbox.mapboxsdk.plugins.locationlayer.Utils;
+
+public class LocationLayerCamera {
+
+ private MapboxMap mapboxMap;
+ private int trackingMode = LocationLayerTracking.NONE;
+ private float bearing = -1;
+
+ public LocationLayerCamera(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
+
+ public void setTrackingMode(@LocationLayerTracking.Type int trackingMode) {
+ this.trackingMode = trackingMode;
+ }
+
+ public void moveToLocation(Location location) {
+ if (trackingMode == LocationLayerTracking.NONE) {
+ return;
+ }
+ buildCameraUpdateFromLocation(location);
+ }
+
+ public void updateBearing(float bearing) {
+ if (trackingMode == LocationLayerTracking.TRACKING_COMPASS) {
+ mapboxMap.setBearing(bearing);
+ }
+ }
+
+ private void buildCameraUpdateFromLocation(Location location) {
+ switch (trackingMode) {
+ case LocationLayerTracking.TRACKING:
+ case LocationLayerTracking.TRACKING_COMPASS:
+ buildTrackingAnimation(location);
+ break;
+ case LocationLayerTracking.TRACKING_GPS:
+ buildTrackingGPSAnimation(location);
+ break;
+ case LocationLayerTracking.TRACKING_GPS_NORTH:
+ buildTrackingGPSNorthAnimation(location);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private 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();
+ }
+
+ private void buildTrackingGPSAnimation(Location location) {
+ MapAnimator.Builder mapAnimation = MapAnimator.builder(mapboxMap);
+ addLatLngAnimator(location, mapAnimation);
+
+ if (!location.hasBearing()) {
+ mapAnimation.build().playTogether();
+ return;
+ }
+
+ float targetBearing = calculateBearing(location);
+ createBearingAnimator(mapAnimation, targetBearing);
+ mapAnimation.build().playTogether();
+ }
+
+ private 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);
+ createBearingAnimator(mapAnimation, targetBearing);
+ mapAnimation.build().playTogether();
+ }
+
+ 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 createBearingAnimator(MapAnimator.Builder mapAnimation, float targetBearing) {
+ BearingAnimator bearingAnimator = new BearingAnimator(targetBearing, 1000);
+ bearingAnimator.setInterpolator(new LinearInterpolator());
+ mapAnimation.addBearingAnimator(bearingAnimator);
+ }
+
+ private float calculateBearing(Location location) {
+ if (location.hasBearing() && bearing > 0) {
+ float bearing = Utils.shortestRotation(location.getBearing(), this.bearing);
+ this.bearing = bearing;
+ return bearing;
+ } else {
+ this.bearing = location.getBearing();
+ return this.bearing;
+ }
+ }
+}
From 5031e328307270468a2ec8a58c277a757dbe82cb Mon Sep 17 00:00:00 2001
From: Dan Nesfeder
Date: Wed, 21 Feb 2018 19:05:55 +0100
Subject: [PATCH 03/24] Update with Render / Camera Modes (#297)
* Update with render / camera modes
* Update camera with mode manager and cancel animation check
* Update method compass name
---
.../locationlayer/LocationLayerTest.java | 23 +--
.../location/CompassListenerActivity.java | 4 +-
.../LocationLayerMapChangeActivity.java | 4 +-
.../location/LocationLayerModesActivity.java | 24 +--
.../ManualLocationUpdatesActivity.java | 4 +-
.../plugins/locationlayer/LocationLayer.java | 137 ++++++++----------
.../locationlayer/LocationLayerPlugin.java | 84 +++++------
.../locationlayer/LocationLayerTracking.java | 68 ---------
.../locationlayer/RenderModeManager.java | 43 ++++++
.../camera/CameraModeManager.java | 49 +++++++
.../camera/LocationLayerCamera.java | 79 +++++-----
.../locationlayer/camera/MapAnimator.java | 17 +--
.../locationlayer/modes/CameraMode.java | 84 +++++++++++
.../RenderMode.java} | 25 ++--
14 files changed, 358 insertions(+), 287 deletions(-)
delete mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/RenderModeManager.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/CameraModeManager.java
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java
rename plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/{LocationLayerMode.java => modes/RenderMode.java} (58%)
diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
index 7698a6b5e..f08c4bcca 100644
--- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
+++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
@@ -10,6 +10,7 @@
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.testapp.activity.location.LocationLayerModesActivity;
import com.mapbox.mapboxsdk.style.layers.Property;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
@@ -85,7 +86,7 @@ public void locationSourceAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
assertTrue(mapboxMap.getSource(LOCATION_SOURCE) != null);
}
});
@@ -97,7 +98,7 @@ public void locationTrackingLayersAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
assertTrue(mapboxMap.getLayer(ACCURACY_LAYER) != null);
assertTrue(mapboxMap.getLayer(BACKGROUND_LAYER) != null);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
@@ -111,7 +112,7 @@ public void locationBearingLayersAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.COMPASS);
assertTrue(mapboxMap.getLayer(ACCURACY_LAYER) != null);
assertTrue(mapboxMap.getLayer(BACKGROUND_LAYER) != null);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
@@ -126,7 +127,7 @@ public void locationNavigationLayersAdded() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.COMPASS);
assertTrue(mapboxMap.getLayer(NAVIGATION_LAYER) != null);
}
});
@@ -138,7 +139,7 @@ public void locationLayerModeCorrectlySetToNone() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
locationLayerPlugin.setLocationLayerEnabled(false);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER).getVisibility().getValue()
@@ -153,11 +154,11 @@ public void onMapChangeLocationLayerRedrawn() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
mapboxMap.setStyleUrl(Style.SATELLITE);
uiController.loopMainThreadForAtLeast(500);
- assertEquals(locationLayerPlugin.getLocationLayerMode(), LocationLayerMode.NORMAL);
+ assertEquals(locationLayerPlugin.getLocationLayerMode(), RenderMode.NORMAL);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER) != null);
assertTrue(mapboxMap.getLayer(FOREGROUND_LAYER).getVisibility().getValue()
.equals(Property.VISIBLE));
@@ -175,11 +176,11 @@ public void whenStaleTimeSet_iconsDoChangeAtAppropriateTime() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
SymbolLayer symbolLayer = mapboxMap.getLayerAs(FOREGROUND_LAYER);
assert symbolLayer != null;
assertThat(symbolLayer.getIconImage().getValue(), equalTo(FOREGROUND_ICON));
- locationLayerPlugin.applyStyle(LocationLayerOptions.builder(context).staleStateDelay(400).build());
+ locationLayerPlugin.applyStyle(context, LocationLayerOptions.builder(context).staleStateDelay(400).build());
locationLayerPlugin.forceLocationUpdate(location);
uiController.loopMainThreadForAtLeast(500);
assertThat(symbolLayer.getIconImage().getValue(), equalTo(FOREGROUND_STALE_ICON));
@@ -193,8 +194,8 @@ public void whenDrawableChanged_continuesUsingStaleIcons() throws Exception {
@Override
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
- locationLayerPlugin.applyStyle(LocationLayerOptions.builder(context).staleStateDelay(100).build());
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
+ locationLayerPlugin.applyStyle(context, LocationLayerOptions.builder(context).staleStateDelay(100).build());
locationLayerPlugin.forceLocationUpdate(location);
uiController.loopMainThreadForAtLeast(200);
rule.getActivity().toggleStyle();
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..0550669db 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
@@ -9,7 +9,7 @@
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.plugins.locationlayer.CompassListener;
-import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.services.android.location.LostLocationEngine;
@@ -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(LocationLayerMode.COMPASS);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.COMPASS);
locationLayerPlugin.addCompassListener(new CompassListener() {
@Override
public void onCompassChanged(float userHeading) {
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 941a86eef..5a72568e6 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
@@ -9,7 +9,7 @@
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.mapboxsdk.plugins.testapp.Utils;
@@ -52,7 +52,7 @@ public void onMapReady(MapboxMap mapboxMap) {
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
locationPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
- locationPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
+ locationPlugin.setLocationLayerMode(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 598a4db0d..2d864843e 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
@@ -19,9 +19,9 @@
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
-import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerTracking;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.OnLocationLayerClickListener;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.services.android.location.LostLocationEngine;
@@ -203,7 +203,7 @@ private void showModeListDialog() {
List modes = new ArrayList<>();
modes.add("Normal");
modes.add("Compass");
- modes.add("Navigation");
+ modes.add("GPS");
ArrayAdapter profileAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, modes);
ListPopupWindow listPopup = new ListPopupWindow(this);
@@ -213,11 +213,11 @@ private void showModeListDialog() {
String selectedMode = modes.get(position);
locationModeBtn.setText(selectedMode);
if (selectedMode.contentEquals("Normal")) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
} else if (selectedMode.contentEquals("Compass")) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.COMPASS);
- } else if (selectedMode.contentEquals("Navigation")) {
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NAVIGATION);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.COMPASS);
+ } else if (selectedMode.contentEquals("GPS")) {
+ locationLayerPlugin.setLocationLayerMode(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(LocationLayerTracking.NONE);
+ locationLayerPlugin.setLocationLayerTracking(CameraMode.NONE);
} else if (selectedTrackingType.contentEquals("Tracking")) {
- locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING);
+ locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING);
} else if (selectedTrackingType.contentEquals("Tracking Compass")) {
- locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING_COMPASS);
+ locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING_COMPASS);
} else if (selectedTrackingType.contentEquals("Tracking GPS")) {
- locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING_GPS);
+ locationLayerPlugin.setLocationLayerTracking(CameraMode.TRACKING_GPS);
} else if (selectedTrackingType.contentEquals("Tracking GPS North")) {
- locationLayerPlugin.setLocationLayerTracking(LocationLayerTracking.TRACKING_GPS_NORTH);
+ locationLayerPlugin.setLocationLayerTracking(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 874e752f0..61e597507 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
@@ -10,7 +10,7 @@
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.mapboxsdk.plugins.testapp.Utils;
@@ -71,7 +71,7 @@ public void onMapReady(MapboxMap mapboxMap) {
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, null);
- locationLayerPlugin.setLocationLayerMode(LocationLayerMode.NORMAL);
+ locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
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 9d868680d..3531069e7 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
@@ -12,6 +12,7 @@
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.layers.Property;
@@ -37,7 +38,6 @@
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.PUCK_ICON;
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;
@@ -65,52 +65,39 @@
final class LocationLayer {
- private final StaleStateRunnable staleStateRunnable;
+ private RenderModeManager renderModeManager;
private final MapboxMap mapboxMap;
- private final Context context;
private float elevation;
private final Map layerMap = new HashMap<>();
private final Map sourceMap = new HashMap<>();
- LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options,
- StaleStateRunnable staleStateRunnable) {
- this.staleStateRunnable = staleStateRunnable;
- this.context = mapView.getContext();
+ LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) {
+ this.renderModeManager = new RenderModeManager(this);
this.mapboxMap = mapboxMap;
- addSources();
+ addLocationSource();
addLayers();
- applyStyle(options);
+ applyStyle(mapView.getContext(), options, false);
}
- private void addLayers() {
- addSymbolLayerToMap(SHADOW_LAYER, BACKGROUND_LAYER);
- addSymbolLayerToMap(BACKGROUND_LAYER, FOREGROUND_LAYER);
- addSymbolLayerToMap(FOREGROUND_LAYER, null);
- addSymbolLayerToMap(LocationLayerConstants.BEARING_LAYER, null);
- addNavigationLayer();
- addAccuracyLayer();
- }
-
- private void addSources() {
- addSource(LOCATION_SOURCE);
+ void updateRenderMode(@RenderMode.Mode int renderMode) {
+ renderModeManager.updateMode(renderMode);
}
- void applyStyle(@NonNull LocationLayerOptions options) {
-
+ 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()));
+ getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor()),
+ isStale);
styleBackground(
getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()),
- getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()));
+ getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()),
+ isStale);
styleBearing(
getDrawable(context, options.bearingDrawable(), options.bearingTintColor()));
- styleNavigation(
- ContextCompat.getDrawable(context, options.navigationDrawable()));
styleAccuracy(options.accuracyAlpha(), options.accuracyColor());
}
@@ -118,13 +105,12 @@ void applyStyle(@NonNull LocationLayerOptions options) {
// Layer action
//
- void setLayersVisibility(boolean visible) {
- layerMap.get(SHADOW_LAYER).setProperties(visibility(visible ? VISIBLE : NONE));
- layerMap.get(FOREGROUND_LAYER).setProperties(visibility(visible ? VISIBLE : NONE));
- layerMap.get(BACKGROUND_LAYER).setProperties(visibility(visible ? VISIBLE : NONE));
- layerMap.get(BEARING_LAYER).setProperties(visibility(visible ? VISIBLE : NONE));
- layerMap.get(ACCURACY_LAYER).setProperties(visibility(visible ? VISIBLE : NONE));
- layerMap.get(NAVIGATION_LAYER).setProperties(visibility(visible ? VISIBLE : NONE));
+ void show() {
+ updateLayerVisibility(VISIBLE);
+ }
+
+ void hide() {
+ updateLayerVisibility(NONE);
}
void setLayerVisibility(String layerId, boolean visible) {
@@ -135,6 +121,15 @@ 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 void addLayerToMap(Layer layer, @Nullable String idBelowLayer) {
if (idBelowLayer == null) {
mapboxMap.addLayer(layer);
@@ -144,38 +139,12 @@ private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) {
layerMap.put(layer.getId(), layer);
}
- private void addNavigationLayer() {
- SymbolLayer navigationLayer = new SymbolLayer(NAVIGATION_LAYER, LOCATION_SOURCE).withProperties(
- 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(navigationLayer, null);
- }
-
private void addAccuracyLayer() {
CircleLayer locationAccuracyLayer = new CircleLayer(ACCURACY_LAYER, LOCATION_SOURCE)
.withProperties(circleRadius(0f));
addLayerToMap(locationAccuracyLayer, BACKGROUND_LAYER);
}
- 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) {
if (location == null) {
return 0;
@@ -193,14 +162,28 @@ void setLocationPoint(Point locationPoint) {
sourceMap.get(LOCATION_SOURCE).setGeoJson(locationPoint);
}
- private void addSource(String sourceId) {
+ private void addLocationSource() {
FeatureCollection emptyFeature = FeatureCollection.fromFeatures(new Feature[] {});
GeoJsonSource locationSource = new GeoJsonSource(
- sourceId,
+ LOCATION_SOURCE,
emptyFeature,
new GeoJsonOptions().withMaxZoom(16));
mapboxMap.addSource(locationSource);
- sourceMap.put(sourceId, locationSource);
+ 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) {
@@ -208,14 +191,15 @@ private void addSymbolLayerToMap(String layerId, String beforeLayerId) {
layer.setProperties(
iconAllowOverlap(true),
iconIgnorePlacement(true),
- iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP),
iconSize(zoom(
exponential(
- stop(16f, iconSize(1.2f)),
- stop(0f, iconSize(1f))
- )
- ))
- );
+ 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);
}
@@ -223,35 +207,28 @@ private void addSymbolLayerToMap(String layerId, String beforeLayerId) {
// Styling
//
- private void styleBackground(Drawable backgroundDrawable, Drawable backgroundDrawableStale) {
+ private void styleBackground(Drawable backgroundDrawable, Drawable backgroundDrawableStale, boolean isStale) {
mapboxMap.addImage(BACKGROUND_ICON, getBitmapFromDrawable(backgroundDrawable));
mapboxMap.addImage(BACKGROUND_STALE_ICON, getBitmapFromDrawable(backgroundDrawableStale));
layerMap.get(BACKGROUND_LAYER).setProperties(
- iconImage(staleStateRunnable.isStale()
- ? BACKGROUND_STALE_ICON : BACKGROUND_ICON));
+ iconImage(isStale ? BACKGROUND_STALE_ICON : BACKGROUND_ICON));
}
private void styleShadow(Drawable shadowDrawable) {
mapboxMap.addImage(SHADOW_ICON, generateShadow(shadowDrawable, elevation));
- layerMap.get(SHADOW_LAYER).setProperties(
- iconImage(SHADOW_ICON));
+ layerMap.get(SHADOW_LAYER).setProperties(iconImage(SHADOW_ICON));
}
- private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale) {
+ 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(staleStateRunnable.isStale()
+ iconImage(isStale
? FOREGROUND_STALE_ICON : FOREGROUND_ICON),
iconRotate(90f));
}
- private void styleNavigation(Drawable navigationDrawable) {
- mapboxMap.addImage(PUCK_ICON, getBitmapFromDrawable(navigationDrawable));
- layerMap.get(NAVIGATION_LAYER).setProperties(iconImage(PUCK_ICON));
- }
-
private void styleBearing(Drawable bearingDrawable) {
mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable));
layerMap.get(BEARING_LAYER).setProperties(
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..0d231b9bd 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
@@ -4,6 +4,7 @@
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
+import android.content.Context;
import android.location.Location;
import android.os.SystemClock;
import android.support.annotation.NonNull;
@@ -22,12 +23,12 @@
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.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 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;
@@ -41,10 +42,10 @@
* The Location layer plugin provides location awareness to your mobile application. Enabling this
* plugin provides a contextual experience to your users by showing an icon representing the users
* current location. A few different modes are offered to provide the right context to your users at
- * the correct time. {@link LocationLayerMode#NORMAL} simply shows the users location on the map
- * represented as a dot. {@link LocationLayerMode#COMPASS} mode allows you to display an arrow icon
+ * the correct time. {@link RenderMode#NORMAL} simply shows the users location on the map
+ * represented as a dot. {@link RenderMode#COMPASS} mode allows you to display an arrow icon
* (by default) that points in the direction the device is pointing in.
- * {@link LocationLayerMode#NAVIGATION} can be used in conjunction with our Navigation SDK to
+ * {@link RenderMode#GPS} can be used in conjunction with our Navigation SDK to
* display a larger icon we call the user puck.
*
* Lastly, {@link LocationLayerPlugin#setLocationLayerEnabled(boolean)} can be used
@@ -69,7 +70,7 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas
private final MapView mapView;
// Enabled booleans
- @LocationLayerMode.Mode
+ @RenderMode.Mode
private int locationLayerMode;
private boolean isEnabled;
@@ -86,7 +87,6 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas
private boolean linearAnimation;
private OnLocationLayerClickListener onLocationLayerClickListener;
- private StaleStateRunnable staleStateRunnable;
private LocationLayerOptions options;
/**
@@ -132,9 +132,8 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa
private void initialize() {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
- staleStateRunnable = new StaleStateRunnable(options.staleStateDelay());
- locationLayerMode = LocationLayerMode.NORMAL;
- locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable);
+ locationLayerMode = RenderMode.NORMAL;
+ locationLayer = new LocationLayer(mapView, mapboxMap, options);
compassManager = new CompassManager(mapView.getContext(), this);
camera = new LocationLayerCamera(mapboxMap);
enableLocationLayerPlugin();
@@ -152,45 +151,45 @@ public void setLocationLayerEnabled(boolean isEnabled) {
/**
* 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
+ * your choice. These modes can be found in the {@link RenderMode} class and the parameter
* only accepts one of those modes. Note that before enabling the My Location layer, you will need
* to ensure that you have the requested the required user location permissions.
*
*
- *
{@link LocationLayerMode#NORMAL}: Display the user location on the map as a small dot
- *
{@link LocationLayerMode#COMPASS}: Display the user location and current heading/bearing
- *
{@link LocationLayerMode#NAVIGATION}: Display the user location on the map using a navigation icon
+ *
{@link RenderMode#NORMAL}: Display the user location on the map as a small dot
+ *
{@link RenderMode#COMPASS}: Display the user location and current heading/bearing
+ *
{@link RenderMode#GPS}: Display the user location on the map using a navigation icon
*
*
- * @param locationLayerMode one of the modes found in {@link LocationLayerMode}
+ * @param locationLayerMode one of the modes found in {@link RenderMode}
* @since 0.1.0
*/
- public void setLocationLayerMode(@LocationLayerMode.Mode int locationLayerMode) {
+ public void setLocationLayerMode(@RenderMode.Mode int locationLayerMode) {
this.locationLayerMode = locationLayerMode;
- if (locationLayerMode == LocationLayerMode.COMPASS) {
+ if (locationLayerMode == RenderMode.COMPASS) {
setLinearAnimation(false);
setNavigationEnabled(false);
setMyBearingEnabled(true);
- } else if (locationLayerMode == LocationLayerMode.NAVIGATION) {
+ } else if (locationLayerMode == RenderMode.GPS) {
setMyBearingEnabled(false);
setNavigationEnabled(true);
- } else if (locationLayerMode == LocationLayerMode.NORMAL) {
+ } else if (locationLayerMode == RenderMode.NORMAL) {
setLinearAnimation(false);
setMyBearingEnabled(false);
setNavigationEnabled(false);
}
}
- public void setLocationLayerTracking(@LocationLayerTracking.Type int trackingMode) {
+ public void setLocationLayerTracking(@CameraMode.Mode int trackingMode) {
if (camera != null) {
- camera.setTrackingMode(trackingMode);
+ camera.setCameraMode(trackingMode);
}
}
/**
* Returns the current location mode being used with this plugin.
*
- * @return on of the {@link LocationLayerMode} values
+ * @return on of the {@link RenderMode} values
* @since 0.1.0
*/
public int getLocationLayerMode() {
@@ -212,7 +211,6 @@ public void onMapChanged(int change) {
@Override
public void isLocationStale(boolean stale) {
- Timber.v("isLocationStale: %b", stale);
locationLayer.locationsStale(stale);
}
@@ -223,15 +221,17 @@ public void isLocationStale(boolean stale) {
* @since 0.1.0
*/
public void applyStyle(@StyleRes int styleRes) {
- applyStyle(LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes));
+ Context context = mapView.getContext();
+ applyStyle(context, LocationLayerOptions.createFromAttributes(context, styleRes));
}
- public void applyStyle(LocationLayerOptions options) {
- locationLayer.applyStyle(options);
+ public void applyStyle(Context context, LocationLayerOptions options) {
+ // TODO get stale state from this class
+ locationLayer.applyStyle(context, options, false);
if (!options.enableStaleState()) {
- staleStateRunnable.reset();
+// staleStateRunnable.reset();
}
- staleStateRunnable.setDelayTime(options.staleStateDelay());
+// staleStateRunnable.setDelayTime(options.staleStateDelay());
}
/**
@@ -283,7 +283,7 @@ public LocationEngine getLocationEngine() {
*/
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
- staleStateRunnable.onStop();
+// staleStateRunnable.onStop();
stopAllAnimations();
if (compassManager != null && compassManager.isSensorAvailable()) {
compassManager.onStop();
@@ -310,13 +310,13 @@ public void onStart() {
}
if (!compassManager.getCompassListeners().isEmpty()
- || (locationLayerMode == LocationLayerMode.COMPASS && compassManager.isSensorAvailable())) {
+ || (locationLayerMode == RenderMode.COMPASS && compassManager.isSensorAvailable())) {
compassManager.onStart();
}
if (mapboxMap != null) {
mapboxMap.addOnCameraMoveListener(this);
}
- staleStateRunnable.addOnLocationStaleListener(this);
+// staleStateRunnable.addOnLocationStaleListener(this);
}
/**
@@ -416,7 +416,7 @@ public void onCompassAccuracyChange(int compassStatus) {
}
private void toggleCameraListener() {
- if (locationLayerMode == LocationLayerMode.NAVIGATION) {
+ if (locationLayerMode == RenderMode.GPS) {
mapboxMap.removeOnCameraMoveListener(this);
return;
}
@@ -429,9 +429,9 @@ private void updateLocation(Location location) {
locationUpdateTimestamp = SystemClock.elapsedRealtime();
return;
}
- if (locationLayerMode == LocationLayerMode.NAVIGATION && location.hasBearing()) {
+ if (locationLayerMode == RenderMode.GPS && location.hasBearing()) {
bearingChangeAnimate(location.getBearing());
- } else if (locationLayerMode != LocationLayerMode.NAVIGATION) {
+ } else if (locationLayerMode != RenderMode.GPS) {
locationLayer.updateAccuracyRadius(location);
}
setLocation(location);
@@ -439,7 +439,7 @@ private void updateLocation(Location location) {
private void updateCameraLocation(Location location) {
if (camera != null) {
- camera.moveToLocation(location);
+ // TODO LocationLayerPlugin#
}
}
@@ -451,7 +451,7 @@ private void enableLocationLayerPlugin() {
}
toggleCameraListener();
- locationLayer.setLayersVisibility(true);
+// locationLayer.setLayersVisibility(true);
}
/**
@@ -461,7 +461,7 @@ private void disableLocationLayerPlugin() {
if (locationEngine != null) {
locationEngine.removeLocationEngineListener(this);
}
- locationLayer.setLayersVisibility(false);
+// locationLayer.setLayersVisibility(false);
}
/**
@@ -473,7 +473,7 @@ private void setLastLocation() {
Location lastLocation = locationEngine.getLastLocation();
if (lastLocation != null) {
setLocation(lastLocation);
- if (locationLayerMode != LocationLayerMode.NAVIGATION) {
+ if (locationLayerMode != RenderMode.GPS) {
locationLayer.updateAccuracyRadius(lastLocation);
}
}
@@ -512,7 +512,7 @@ private void stopAllAnimations() {
@SuppressWarnings( {"MissingPermission"})
private void mapStyleFinishedLoading() {
// recreate runtime style components
- locationLayer = new LocationLayer(mapView, mapboxMap, options, staleStateRunnable);
+ locationLayer = new LocationLayer(mapView, mapboxMap, options);
// reset state
setLocationLayerMode(locationLayerMode);
setBearing(previousMagneticHeading);
@@ -577,7 +577,7 @@ public void onCameraMove() {
*/
private void setLocation(final Location location) {
this.location = location;
- staleStateRunnable.updateLatestLocationTime();
+// staleStateRunnable.updateLatestLocationTime();
// Convert the new location to a Point object.
Point newPoint = Point.fromCoordinates(new double[] {location.getLongitude(),
@@ -668,13 +668,13 @@ public void onAnimationUpdate(ValueAnimator valueAnimator) {
private void updateCameraBearing(float bearing) {
if (camera != null) {
- camera.updateBearing(bearing);
+// camera.updateFromBearing(bearing);
}
}
private void setBearing(float bearing) {
locationLayer.setLayerBearing(
- locationLayerMode == LocationLayerMode.NAVIGATION
+ locationLayerMode == RenderMode.GPS
? NAVIGATION_LAYER : BEARING_LAYER, bearing
);
}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java
deleted file mode 100644
index 8e9754adf..000000000
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTracking.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package com.mapbox.mapboxsdk.plugins.locationlayer;
-
-import android.location.Location;
-import android.support.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Contains the variety of Location Layer modes which shape the behavior of the plugin.
- *
- * @since 0.1.0
- */
-public final class LocationLayerTracking {
-
- private LocationLayerTracking() {
- // Class should not be initialized
- }
-
- /**
- * Determine the camera tracking behavior in the {@link LocationLayerPlugin}.
- *
- * @since 0.4.0
- */
- @IntDef( {NONE, TRACKING, TRACKING_COMPASS, TRACKING_GPS, TRACKING_GPS_NORTH})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {
- }
-
- /**
- * No camera tracking.
- *
- * @since 0.4.0
- */
- public static final int NONE = 0x00000000;
-
- /**
- * Tracks the user location.
- *
- * @since 0.4.0
- */
- public static final int TRACKING = 0x0000006;
-
- /**
- * Tracks the user location, with camera bearing
- * based on the bearing provided by the compass.
- *
- * @since 0.4.0
- */
- public static final int TRACKING_COMPASS = 0x00000010;
-
- /**
- * Tracks the user location, with camera bearing
- * based on the bearing provided by a normalized {@link Location#getBearing()}.
- *
- * @since 0.4.0
- */
- public static final int TRACKING_GPS = 0x00000014;
-
-
- /**
- * Tracks the user location, with camera bearing
- * always set to north.
- *
- * @since 0.4.0
- */
- public static final int TRACKING_GPS_NORTH = 0x00000018;
-}
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
new file mode 100644
index 000000000..75c9bc53e
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/RenderModeManager.java
@@ -0,0 +1,43 @@
+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;
+ }
+ }
+}
+
+
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
new file mode 100644
index 000000000..620a4a92d
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/CameraModeManager.java
@@ -0,0 +1,49 @@
+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/LocationLayerCamera.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/LocationLayerCamera.java
index 88d6e9d2e..510069ece 100644
--- 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
@@ -5,54 +5,47 @@
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerTracking;
import com.mapbox.mapboxsdk.plugins.locationlayer.Utils;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode;
public class LocationLayerCamera {
private MapboxMap mapboxMap;
- private int trackingMode = LocationLayerTracking.NONE;
- private float bearing = -1;
+ private CameraModeManager cameraModeManager;
+ private MapAnimator mapAnimator;
public LocationLayerCamera(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
+ cameraModeManager = new CameraModeManager(this);
}
- public void setTrackingMode(@LocationLayerTracking.Type int trackingMode) {
- this.trackingMode = trackingMode;
+ public void setCameraMode(@CameraMode.Mode int cameraMode) {
+ cancelRunningAnimator();
+ cameraModeManager.setCameraMode(cameraMode);
}
- public void moveToLocation(Location location) {
- if (trackingMode == LocationLayerTracking.NONE) {
- return;
- }
- buildCameraUpdateFromLocation(location);
+ public void updateFromCompassBearing(float bearing) {
+ cameraModeManager.updateFromBearing(bearing);
}
- public void updateBearing(float bearing) {
- if (trackingMode == LocationLayerTracking.TRACKING_COMPASS) {
- mapboxMap.setBearing(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();
}
- private void buildCameraUpdateFromLocation(Location location) {
- switch (trackingMode) {
- case LocationLayerTracking.TRACKING:
- case LocationLayerTracking.TRACKING_COMPASS:
- buildTrackingAnimation(location);
- break;
- case LocationLayerTracking.TRACKING_GPS:
- buildTrackingGPSAnimation(location);
- break;
- case LocationLayerTracking.TRACKING_GPS_NORTH:
- buildTrackingGPSNorthAnimation(location);
- break;
- default:
- break;
+ void buildBearingGPSAnimation(Location location) {
+ if (location.hasBearing()) {
+ buildBearingAnimation(location.getBearing());
}
}
- private void buildTrackingAnimation(Location location) {
+ void buildTrackingAnimation(Location location) {
LatLng target = new LatLng(location);
LatLngAnimator latLngAnimator = new LatLngAnimator(target, 1000);
@@ -64,7 +57,7 @@ private void buildTrackingAnimation(Location location) {
.playTogether();
}
- private void buildTrackingGPSAnimation(Location location) {
+ void buildTrackingGPSAnimation(Location location) {
MapAnimator.Builder mapAnimation = MapAnimator.builder(mapboxMap);
addLatLngAnimator(location, mapAnimation);
@@ -73,12 +66,11 @@ private void buildTrackingGPSAnimation(Location location) {
return;
}
- float targetBearing = calculateBearing(location);
- createBearingAnimator(mapAnimation, targetBearing);
+ addBearingAnimator(mapAnimation, location.getBearing());
mapAnimation.build().playTogether();
}
- private void buildTrackingGPSNorthAnimation(Location location) {
+ void buildTrackingGPSNorthAnimation(Location location) {
MapAnimator.Builder mapAnimation = MapAnimator.builder(mapboxMap);
addLatLngAnimator(location, mapAnimation);
@@ -89,10 +81,16 @@ private void buildTrackingGPSNorthAnimation(Location location) {
}
float targetBearing = Utils.shortestRotation(0, (float) bearing);
- createBearingAnimator(mapAnimation, targetBearing);
+ 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);
@@ -100,20 +98,9 @@ private void addLatLngAnimator(Location location, MapAnimator.Builder mapAnimati
mapAnimation.addLatLngAnimator(latLngAnimator);
}
- private void createBearingAnimator(MapAnimator.Builder mapAnimation, float targetBearing) {
+ private void addBearingAnimator(MapAnimator.Builder mapAnimation, float targetBearing) {
BearingAnimator bearingAnimator = new BearingAnimator(targetBearing, 1000);
bearingAnimator.setInterpolator(new LinearInterpolator());
mapAnimation.addBearingAnimator(bearingAnimator);
}
-
- private float calculateBearing(Location location) {
- if (location.hasBearing() && bearing > 0) {
- float bearing = Utils.shortestRotation(location.getBearing(), this.bearing);
- this.bearing = bearing;
- return bearing;
- } else {
- this.bearing = location.getBearing();
- return this.bearing;
- }
- }
}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java
index 8ebc21292..980492ab2 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/camera/MapAnimator.java
@@ -9,6 +9,7 @@
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.plugins.locationlayer.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -43,6 +44,10 @@ public void playSequentially(@Nullable Animator.AnimatorListener listener) {
playSequentially();
}
+ public boolean isRunning() {
+ return animatorSet.isRunning();
+ }
+
public void cancel() {
animatorSet.cancel();
}
@@ -105,7 +110,7 @@ public void onAnimationUpdate(ValueAnimator animation) {
public Builder addBearingAnimator(@NonNull BearingAnimator bearingAnimator) {
float currentBearing = (float) currentPosition.bearing;
- float normalizedTargetBearing = normalizeBearing(currentBearing, bearingAnimator.getTargetBearing());
+ float normalizedTargetBearing = Utils.shortestRotation(currentBearing, bearingAnimator.getTargetBearing());
if (currentBearing == normalizedTargetBearing) {
return this;
}
@@ -147,14 +152,4 @@ public MapAnimator build() {
return new MapAnimator(animators);
}
}
-
- private static float normalizeBearing(float currentBearing, float targetBearing) {
- double diff = currentBearing - targetBearing;
- if (diff > 180.0f) {
- targetBearing += 360.0f;
- } else if (diff < -180.0f) {
- targetBearing -= 360.f;
- }
- return targetBearing;
- }
}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java
new file mode 100644
index 000000000..6672ea2e8
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java
@@ -0,0 +1,84 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer.modes;
+
+import android.location.Location;
+import android.support.annotation.IntDef;
+
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Contains the variety of Location Layer modes which shape the behavior of the plugin.
+ *
+ * @since 0.1.0
+ */
+public final class CameraMode {
+
+ private CameraMode() {
+ // Class should not be initialized
+ }
+
+ /**
+ * Determine the camera tracking behavior in the {@link LocationLayerPlugin}.
+ *
+ * @since 0.4.0
+ */
+ @IntDef( {NONE, NONE_COMPASS, NONE_GPS, TRACKING, TRACKING_COMPASS, TRACKING_GPS, TRACKING_GPS_NORTH})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Mode {
+ }
+
+ /**
+ * No camera tracking.
+ *
+ * @since 0.4.0
+ */
+ public static final int NONE = 0x00000000;
+
+ /**
+ * Camera does not track location, but does track compass bearing.
+ *
+ * @since 0.4.0
+ */
+ public static final int NONE_COMPASS = 0x00000010;
+
+ /**
+ * Camera does not track location, but does track GPS {@link Location} bearing.
+ *
+ * @since 0.4.0
+ */
+ public static final int NONE_GPS = 0x00000016;
+
+ /**
+ * Camera tracks the user location.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING = 0x00000018;
+
+ /**
+ * Camera tracks the user location, with bearing
+ * provided by a compass.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING_COMPASS = 0x00000020;
+
+ /**
+ * Camera tracks the user location, with bearing
+ * provided by a normalized {@link Location#getBearing()}.
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING_GPS = 0x00000022;
+
+
+ /**
+ * Camera tracks the user location, with bearing
+ * always set to north (0).
+ *
+ * @since 0.4.0
+ */
+ public static final int TRACKING_GPS_NORTH = 0x00000024;
+}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
similarity index 58%
rename from plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java
rename to plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
index f8226b2dc..a7326410f 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerMode.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
@@ -1,7 +1,9 @@
-package com.mapbox.mapboxsdk.plugins.locationlayer;
+package com.mapbox.mapboxsdk.plugins.locationlayer.modes;
import android.support.annotation.IntDef;
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -10,9 +12,9 @@
*
* @since 0.1.0
*/
-public final class LocationLayerMode {
+public final class RenderMode {
- private LocationLayerMode() {
+ private RenderMode() {
// Class should not be initialized
}
@@ -24,29 +26,30 @@ private LocationLayerMode() {
*
* @since 0.1.0
*/
- @IntDef( {COMPASS, NAVIGATION, NORMAL})
- @Retention(RetentionPolicy.SOURCE)
+ @IntDef( {COMPASS, GPS, NORMAL})
+ public @Retention(RetentionPolicy.SOURCE)
@interface Mode {
}
/**
- * Tracking the bearing of the user based on sensor data.
+ * Basic tracking is enabled, bearing ignored.
*
* @since 0.1.0
*/
- public static final int COMPASS = 0x00000004;
+ public static final int NORMAL = 0x00000012;
/**
- * Tracking the user location in navigation mode.
+ * Tracking the user location with bearing considered
+ * from a {@link com.mapbox.mapboxsdk.plugins.locationlayer.CompassManager}.
*
* @since 0.1.0
*/
- public static final int NAVIGATION = 0x00000008;
+ public static final int COMPASS = 0x00000004;
/**
- * Basic tracking is enabled.
+ * Tracking the user location with bearing considered from {@link android.location.Location}.
*
* @since 0.1.0
*/
- public static final int NORMAL = 0x00000012;
+ public static final int GPS = 0x00000008;
}
From b66d653fbca97cecbded617662a81667215bc9a2 Mon Sep 17 00:00:00 2001
From: Dan Nesfeder
Date: Thu, 22 Feb 2018 17:36:42 +0100
Subject: [PATCH 04/24] Add animator class (#302)
* initial LocationLayerPlugin cleanup
* added the animator class
* animator implementation in the LocationLayer
* reworked location layer camera
* added Animator to LocationLayerPlugin
* adjusted location activities
* animator order fix
* last values ordering fix
* string fixes
* Fix GPS layer
* using previous animated value when starting a new one
* small tweaks
* setting accuracy ring only if using the right mode
---
.../location/CompassListenerActivity.java | 4 +-
.../LocationLayerMapChangeActivity.java | 2 +-
.../location/LocationLayerModesActivity.java | 19 +-
.../ManualLocationUpdatesActivity.java | 2 +-
.../layout/activity_location_layer_mode.xml | 4 +-
app/src/main/res/values/strings.xml | 1 +
.../plugins/locationlayer/CompassManager.java | 60 +-
.../plugins/locationlayer/LocationLayer.java | 234 +++++---
.../locationlayer/LocationLayerAnimator.java | 124 +++++
.../locationlayer/LocationLayerCamera.java | 69 +++
.../locationlayer/LocationLayerConstants.java | 6 +-
.../locationlayer/LocationLayerOptions.java | 8 +-
.../locationlayer/LocationLayerPlugin.java | 522 +++++-------------
.../OnLocationStaleListener.java | 4 +-
.../locationlayer/RenderModeManager.java | 43 --
.../locationlayer/StaleStateRunnable.java | 57 +-
.../locationlayer/camera/BearingAnimator.java | 7 +-
.../camera/CameraModeManager.java | 49 --
.../locationlayer/camera/LatLngAnimator.java | 10 +-
.../camera/LocationLayerCamera.java | 106 ----
20 files changed, 568 insertions(+), 763 deletions(-)
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java
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/RenderModeManager.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/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 0550669db..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(null);
+ //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 2d864843e..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
@@ -91,8 +91,7 @@ public void onMapReady(MapboxMap mapboxMap) {
locationEngine.addLocationEngineListener(this);
locationEngine.activate();
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
- locationLayerPlugin.setOnLocationClickListener(this);
- locationLayerPlugin.setLocationLayerEnabled(true);
+ locationLayerPlugin.addOnLocationClickListener(this);
getLifecycle().addObserver(locationLayerPlugin);
}
@@ -213,11 +212,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 +239,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);
}
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
+ NormalTrackingCompassNav
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..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
@@ -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) {
for (CompassListener compassListener : compassListeners) {
- compassListener.onCompassChanged((float) Math.toDegrees(orientation[0]));
+ compassListener.onCompassChanged(heading);
}
+ lastHeading = 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/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java
index 3531069e7..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
@@ -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,35 +62,31 @@
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 boolean isStale;
- private RenderModeManager renderModeManager;
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.renderModeManager = new RenderModeManager(this);
this.mapboxMap = mapboxMap;
+ this.context = mapView.getContext();
addLocationSource();
addLayers();
- applyStyle(mapView.getContext(), options, false);
- }
-
- void updateRenderMode(@RenderMode.Mode int renderMode) {
- renderModeManager.updateMode(renderMode);
+ 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()),
@@ -99,6 +94,39 @@ 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) {
+ this.renderMode = renderMode;
+ hide();
+
+ 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;
+ default:
+ break;
+ }
+ }
+
+ int getRenderMode() {
+ return renderMode;
}
//
@@ -106,28 +134,48 @@ void applyStyle(@NonNull Context context, @NonNull LocationLayerOptions options,
//
void show() {
- updateLayerVisibility(VISIBLE);
+ setRenderMode(renderMode);
}
void hide() {
- updateLayerVisibility(NONE);
+ for (Layer layer : layerMap.values()) {
+ layer.setProperties(visibility(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 addLayers() {
+ addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER);
+ addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER);
+ addSymbolLayer(FOREGROUND_LAYER, null);
+ addSymbolLayer(LocationLayerConstants.BEARING_LAYER, null);
+ addAccuracyLayer();
}
- void updateAccuracyRadius(Location location) {
- CircleLayer accuracyLayer = (CircleLayer) mapboxMap.getLayer(ACCURACY_LAYER);
- if (accuracyLayer != null && accuracyLayer.getVisibility().isValue()) {
- accuracyLayer.setProperties(
- circleRadius(calculateZoomLevelRadius(location))
- );
- }
+ 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 +187,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) layerMap.get(ACCURACY_LAYER);
+ if (accuracyLayer != null && (renderMode == RenderMode.COMPASS || renderMode == RenderMode.NORMAL)) {
+ accuracyLayer.setProperties(
+ circleRadius(calculateZoomLevelRadius(location))
+ );
+ }
}
private float calculateZoomLevelRadius(Location location) {
@@ -158,10 +213,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 +223,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);
+ private void setLocationPoint(Point locationPoint) {
+ sourceMap.get(LOCATION_SOURCE).setGeoJson(locationPoint);
}
//
@@ -215,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(
@@ -244,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)}));
@@ -251,15 +293,11 @@ 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) {
- 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));
}
//
@@ -271,9 +309,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/LocationLayerAnimator.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java
new file mode 100644
index 000000000..f94d6c62b
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerAnimator.java
@@ -0,0 +1,124 @@
+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 previousLocation, @NonNull Location newLocation) {
+ 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(previousBearing, newLocation.getBearing(), 1000);
+ // FIXME: 22/02/2018 evaluate duration of animation better
+
+ latLngAnimator.addUpdateListener(latLngUpdateListener);
+ gpsBearingAnimator.addUpdateListener(gpsBearingUpdateListener);
+
+ latLngAnimator.start();
+ gpsBearingAnimator.start();
+ }
+
+ void feedNewCompassBearing(float previousCompassBearing, float targetCompassBearing) {
+ cancelCompassAnimations();
+ compassBearingAnimator = new BearingAnimator(previousCompassBearing, targetCompassBearing, 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();
+ latLngAnimator.removeAllUpdateListeners();
+ }
+
+ if (gpsBearingAnimator != null) {
+ gpsBearingAnimator.cancel();
+ gpsBearingAnimator.removeAllUpdateListeners();
+ }
+ }
+
+ private void cancelCompassAnimations() {
+ if (compassBearingAnimator != null) {
+ compassBearingAnimator.cancel();
+ compassBearingAnimator.removeAllUpdateListeners();
+ }
+ }
+}
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..2b9f6ea22
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerCamera.java
@@ -0,0 +1,69 @@
+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;
+ mapboxMap.cancelTransitions();
+ }
+
+ 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/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/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 0d231b9bd..de56b11a1 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,19 +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.content.Context;
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;
@@ -22,30 +18,26 @@
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.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;
+
+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
* plugin provides a contextual experience to your users by showing an icon representing the users
* current location. A few different modes are offered to provide the right context to your users at
- * the correct time. {@link RenderMode#NORMAL} simply shows the users location on the map
- * represented as a dot. {@link RenderMode#COMPASS} mode allows you to display an arrow icon
+ * the correct time. {@link LocationLayerMode#NORMAL} simply shows the users location on the map
+ * represented as a dot. {@link LocationLayerMode#COMPASS} mode allows you to display an arrow icon
* (by default) that points in the direction the device is pointing in.
- * {@link RenderMode#GPS} can be used in conjunction with our Navigation SDK to
+ * {@link LocationLayerMode#NAVIGATION} can be used in conjunction with our Navigation SDK to
* display a larger icon we call the user puck.
*
* Lastly, {@link LocationLayerPlugin#setLocationLayerEnabled(boolean)} can be used
@@ -62,32 +54,24 @@ 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 LocationEngine locationEngine;
+ private CompassManager compassManager;
- // Enabled booleans
- @RenderMode.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 LocationLayer locationLayer;
+ private LocationLayerCamera locationLayerCamera;
- private long locationUpdateTimestamp;
- private boolean linearAnimation;
+ private LocationLayerAnimator locationLayerAnimator;
+ private Location lastLocation;
- private OnLocationLayerClickListener onLocationLayerClickListener;
- private LocationLayerOptions options;
+ private boolean isEnabled;
+ private StaleStateRunnable staleStateRunnable;
+ private final CopyOnWriteArrayList onLocationStaleListeners
+ = new CopyOnWriteArrayList<>();
+ private final CopyOnWriteArrayList onLocationLayerClickListeners
+ = new CopyOnWriteArrayList<>();
/**
* Construct a {@code LocationLayerPlugin}
@@ -116,7 +100,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,22 +109,30 @@ 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);
- locationLayerMode = RenderMode.NORMAL;
+
+ mapView.addOnMapChangedListener(this);
+ mapboxMap.addOnMapClickListener(this);
+
+ compassManager = new CompassManager(mapView.getContext());
+ compassManager.addCompassListener(this);
+ staleStateRunnable = new StaleStateRunnable(this, options.staleStateDelay());
+
locationLayer = new LocationLayer(mapView, mapboxMap, options);
- compassManager = new CompassManager(mapView.getContext(), this);
- camera = new LocationLayerCamera(mapboxMap);
+ locationLayerCamera = new LocationLayerCamera(mapboxMap);
+ locationLayerAnimator = new LocationLayerAnimator();
+ locationLayerAnimator.addListener(locationLayer);
+ locationLayerAnimator.addListener(locationLayerCamera);
+
enableLocationLayerPlugin();
}
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
public void setLocationLayerEnabled(boolean isEnabled) {
- this.isEnabled = isEnabled;
if (isEnabled) {
enableLocationLayerPlugin();
} else {
@@ -149,53 +140,65 @@ public void setLocationLayerEnabled(boolean isEnabled) {
}
}
+ private void enableLocationLayerPlugin() {
+ isEnabled = true;
+
+ if (locationEngine != null) {
+ locationEngine.addLocationEngineListener(this);
+ }
+ setLastLocation();
+ setLastCompassHeading();
+ locationLayer.show();
+ }
+
+ private void disableLocationLayerPlugin() {
+ isEnabled = false;
+
+ if (locationEngine != null) {
+ locationEngine.removeLocationEngineListener(this);
+ }
+ locationLayer.hide();
+ }
+
/**
* 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 RenderMode} class and the parameter
+ * your choice. These modes can be found in the {@link LocationLayerMode} class and the parameter
* only accepts one of those modes. Note that before enabling the My Location layer, you will need
* to ensure that you have the requested the required user location permissions.
*
*
- *
{@link RenderMode#NORMAL}: Display the user location on the map as a small dot
- *
{@link RenderMode#COMPASS}: Display the user location and current heading/bearing
- *
{@link RenderMode#GPS}: Display the user location on the map using a navigation icon
+ *
{@link LocationLayerMode#NORMAL}: Display the user location on the map as a small dot
+ *
{@link LocationLayerMode#COMPASS}: Display the user location and current heading/bearing
+ *
{@link LocationLayerMode#NAVIGATION}: Display the user location on the map using a navigation icon
*
*
- * @param locationLayerMode one of the modes found in {@link RenderMode}
+ * @param locationLayerMode one of the modes found in {@link LocationLayerMode}
* @since 0.1.0
*/
- public void setLocationLayerMode(@RenderMode.Mode int locationLayerMode) {
- this.locationLayerMode = locationLayerMode;
- if (locationLayerMode == RenderMode.COMPASS) {
- setLinearAnimation(false);
- setNavigationEnabled(false);
- setMyBearingEnabled(true);
- } else if (locationLayerMode == RenderMode.GPS) {
- setMyBearingEnabled(false);
- setNavigationEnabled(true);
- } else if (locationLayerMode == RenderMode.NORMAL) {
- setLinearAnimation(false);
- setMyBearingEnabled(false);
- setNavigationEnabled(false);
- }
+ public void setCameraMode(@CameraMode.Mode int cameraMode) {
+ locationLayerCamera.setCameraMode(cameraMode);
}
- public void setLocationLayerTracking(@CameraMode.Mode int trackingMode) {
- if (camera != null) {
- camera.setCameraMode(trackingMode);
- }
+ @CameraMode.Mode
+ public int getCameraMode() {
+ return locationLayerCamera.getCameraMode();
+ }
+
+ public void setRenderMode(@RenderMode.Mode int renderMode) {
+ locationLayer.setRenderMode(renderMode);
+ }
+
+ @RenderMode.Mode
+ public int getRenderMode() {
+ return locationLayer.getRenderMode();
}
/**
* Returns the current location mode being used with this plugin.
*
- * @return on of the {@link RenderMode} values
+ * @return on of the {@link LocationLayerMode} values
* @since 0.1.0
*/
- public int getLocationLayerMode() {
- return locationLayerMode;
- }
-
public LocationLayerOptions getLocationLayerOptions() {
return options;
}
@@ -203,15 +206,19 @@ public LocationLayerOptions getLocationLayerOptions() {
@Override
public void onMapChanged(int change) {
if (change == MapView.WILL_START_LOADING_MAP) {
- stopAllAnimations();
+ locationLayerAnimator.cancelAllAnimations();
} else if (change == MapView.DID_FINISH_LOADING_STYLE) {
mapStyleFinishedLoading();
}
}
@Override
- public void isLocationStale(boolean stale) {
- locationLayer.locationsStale(stale);
+ public void onStaleStateChange(boolean isStale) {
+ locationLayer.setLocationsStale(isStale);
+
+ for (OnLocationStaleListener listener : onLocationStaleListeners) {
+ listener.onStaleStateChange(isStale);
+ }
}
/**
@@ -221,17 +228,15 @@ public void isLocationStale(boolean stale) {
* @since 0.1.0
*/
public void applyStyle(@StyleRes int styleRes) {
- Context context = mapView.getContext();
- applyStyle(context, LocationLayerOptions.createFromAttributes(context, styleRes));
+ applyStyle(LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes));
}
- public void applyStyle(Context context, LocationLayerOptions options) {
- // TODO get stale state from this class
- locationLayer.applyStyle(context, options, false);
+ public void applyStyle(LocationLayerOptions options) {
+ locationLayer.applyStyle(options);
if (!options.enableStaleState()) {
-// staleStateRunnable.reset();
+ staleStateRunnable.onStop();
}
-// staleStateRunnable.setDelayTime(options.staleStateDelay());
+ staleStateRunnable.setDelayTime(options.staleStateDelay());
}
/**
@@ -243,7 +248,6 @@ public void applyStyle(Context context, LocationLayerOptions options) {
*/
public void forceLocationUpdate(@Nullable Location location) {
updateLocation(location);
- updateCameraLocation(location);
}
/**
@@ -258,7 +262,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 +279,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 +289,37 @@ public void onStop() {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
if (isEnabled) {
- setLocationLayerMode(locationLayerMode);
- }
-
- if (!compassManager.getCompassListeners().isEmpty()
- || (locationLayerMode == RenderMode.COMPASS && compassManager.isSensorAvailable())) {
- compassManager.onStart();
+ if (locationEngine != null) {
+ locationEngine.addLocationEngineListener(this);
+ }
+ setLastLocation();
+ setLastCompassHeading();
}
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();
+ locationLayerAnimator.cancelAllAnimations();
+ if (locationEngine != null) {
+ locationEngine.removeLocationEngineListener(this);
+ }
+ if (mapboxMap != null) {
+ mapboxMap.removeOnCameraMoveListener(this);
+ }
}
/**
@@ -353,20 +332,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 +351,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 +387,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 +399,30 @@ public void onCompassAccuracyChange(int compassStatus) {
// Currently don't handle this inside SDK
}
- private void toggleCameraListener() {
- if (locationLayerMode == RenderMode.GPS) {
- mapboxMap.removeOnCameraMoveListener(this);
- return;
- }
- mapboxMap.addOnCameraMoveListener(this);
- }
-
- private void updateLocation(Location location) {
- this.location = location;
- if (location == null) {
- locationUpdateTimestamp = SystemClock.elapsedRealtime();
- return;
- }
- if (locationLayerMode == RenderMode.GPS && location.hasBearing()) {
- bearingChangeAnimate(location.getBearing());
- } else if (locationLayerMode != RenderMode.GPS) {
- locationLayer.updateAccuracyRadius(location);
- }
- setLocation(location);
- }
-
- private void updateCameraLocation(Location location) {
- if (camera != null) {
- // TODO LocationLayerPlugin#
- }
- }
-
- 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 != RenderMode.GPS) {
- 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,60 +433,15 @@ private void stopAllAnimations() {
private void mapStyleFinishedLoading() {
// recreate runtime style components
locationLayer = new LocationLayer(mapView, mapboxMap, options);
- // reset state
- setLocationLayerMode(locationLayerMode);
- setBearing(previousMagneticHeading);
- updateCameraBearing(previousMagneticHeading);
- if (previousPoint != null) {
- locationLayer.setLocationPoint(previousPoint);
- }
- }
-
- /**
- * 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);
+ setLastLocation();
+ setLastCompassHeading();
}
@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 +450,20 @@ public void onCameraMove() {
* @param location the latest user location
* @since 0.1.0
*/
- private void setLocation(final Location location) {
- this.location = location;
-// 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) {
+ private void updateLocation(final Location location) {
+ if (location == null) {
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.updateFromBearing(bearing);
+ staleStateRunnable.updateLatestLocationTime();
+ if (lastLocation != null) {
+ locationLayerAnimator.feedNewLocation(lastLocation, location);
}
- }
- private void setBearing(float bearing) {
- locationLayer.setLayerBearing(
- locationLayerMode == RenderMode.GPS
- ? NAVIGATION_LAYER : BEARING_LAYER, bearing
- );
+ lastLocation = 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) {
+ locationLayerAnimator.feedNewCompassBearing(compassManager.getLastHeading(), 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/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;
- }
- }
-}
-
-
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);
}
}
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..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
@@ -7,10 +7,11 @@ public class BearingAnimator extends ValueAnimator {
private float targetBearing;
- public BearingAnimator(double targetBearing, long duration) {
- setEvaluator(new FloatEvaluator());
+ public BearingAnimator(float previous, float target, long duration) {
setDuration(duration);
- this.targetBearing = (float) targetBearing;
+ setEvaluator(new FloatEvaluator());
+ 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..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
@@ -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);
+ setObjectValues(previous, target);
setEvaluator(new LatLngEvaluator());
+ 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 4588147e6d9095e378b8406da34520bfc9f0a74f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Paczos?=
Date: Fri, 23 Feb 2018 09:00:20 +0100
Subject: [PATCH 05/24] Cleanup stale runnable (#304)
---
.../locationlayer/LocationLayerPlugin.java | 20 ++++++-----
...teRunnable.java => StaleStateManager.java} | 36 +++++++++----------
2 files changed, 29 insertions(+), 27 deletions(-)
rename plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/{StaleStateRunnable.java => StaleStateManager.java} (64%)
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 de56b11a1..d917fe8fe 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
@@ -25,8 +25,6 @@
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;
@@ -67,7 +65,7 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas
private Location lastLocation;
private boolean isEnabled;
- private StaleStateRunnable staleStateRunnable;
+ private StaleStateManager staleStateManager;
private final CopyOnWriteArrayList onLocationStaleListeners
= new CopyOnWriteArrayList<>();
private final CopyOnWriteArrayList onLocationLayerClickListeners
@@ -120,7 +118,7 @@ private void initialize() {
compassManager = new CompassManager(mapView.getContext());
compassManager.addCompassListener(this);
- staleStateRunnable = new StaleStateRunnable(this, options.staleStateDelay());
+ staleStateManager = new StaleStateManager(this, options.staleStateDelay());
locationLayer = new LocationLayer(mapView, mapboxMap, options);
locationLayerCamera = new LocationLayerCamera(mapboxMap);
@@ -221,6 +219,10 @@ public void onStaleStateChange(boolean isStale) {
}
}
+ public boolean isLocationStale() {
+ return staleStateManager.isStale();
+ }
+
/**
* Apply a new Location Layer style after the {@link LocationLayerPlugin} has been constructed.
*
@@ -234,9 +236,9 @@ public void applyStyle(@StyleRes int styleRes) {
public void applyStyle(LocationLayerOptions options) {
locationLayer.applyStyle(options);
if (!options.enableStaleState()) {
- staleStateRunnable.onStop();
+ staleStateManager.onStop();
}
- staleStateRunnable.setDelayTime(options.staleStateDelay());
+ staleStateManager.setDelayTime(options.staleStateDelay());
}
/**
@@ -299,7 +301,7 @@ public void onStart() {
mapboxMap.addOnCameraMoveListener(this);
}
if (options.enableStaleState()) {
- staleStateRunnable.onStart();
+ staleStateManager.onStart();
}
compassManager.onStart();
}
@@ -311,7 +313,7 @@ public void onStart() {
*/
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
- staleStateRunnable.onStop();
+ staleStateManager.onStop();
compassManager.onStop();
locationLayerAnimator.cancelAllAnimations();
if (locationEngine != null) {
@@ -455,7 +457,7 @@ private void updateLocation(final Location location) {
return;
}
- staleStateRunnable.updateLatestLocationTime();
+ staleStateManager.updateLatestLocationTime();
if (lastLocation != null) {
locationLayerAnimator.feedNewLocation(lastLocation, location);
}
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/StaleStateManager.java
similarity index 64%
rename from plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateRunnable.java
rename to plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateManager.java
index 0f288a36d..0d7d0af62 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/StaleStateManager.java
@@ -1,10 +1,6 @@
package com.mapbox.mapboxsdk.plugins.locationlayer;
import android.os.Handler;
-import android.support.annotation.NonNull;
-
-import java.util.ArrayList;
-import java.util.List;
/**
* Class controls the location layer stale state when the {@link android.location.Location} hasn't
@@ -14,24 +10,26 @@
*
* @since 0.4.0
*/
-class StaleStateRunnable implements Runnable {
+class StaleStateManager {
private final OnLocationStaleListener innerOnLocationStaleListeners;
private final Handler handler;
private boolean isStale;
private long delayTime;
- StaleStateRunnable(OnLocationStaleListener innerListener, long delayTime) {
+ StaleStateManager(OnLocationStaleListener innerListener, long delayTime) {
innerOnLocationStaleListeners = innerListener;
this.delayTime = delayTime;
handler = new Handler();
}
- @Override
- public void run() {
- isStale = true;
- innerOnLocationStaleListeners.onStaleStateChange(true);
- }
+ private Runnable staleStateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ isStale = true;
+ innerOnLocationStaleListeners.onStaleStateChange(true);
+ }
+ };
boolean isStale() {
return isStale;
@@ -42,24 +40,26 @@ void updateLatestLocationTime() {
isStale = false;
innerOnLocationStaleListeners.onStaleStateChange(false);
}
-
- handler.removeCallbacksAndMessages(this);
- handler.postDelayed(this, delayTime);
+ postTheCallback();
}
void setDelayTime(long delayTime) {
this.delayTime = delayTime;
- handler.removeCallbacksAndMessages(this);
- handler.postDelayed(this, delayTime);
+ postTheCallback();
}
void onStart() {
if (!isStale) {
- handler.postDelayed(this, delayTime);
+ postTheCallback();
}
}
void onStop() {
- handler.removeCallbacksAndMessages(this);
+ handler.removeCallbacksAndMessages(null);
+ }
+
+ private void postTheCallback() {
+ handler.removeCallbacksAndMessages(null);
+ handler.postDelayed(staleStateRunnable, delayTime);
}
}
From 612f227c7042f440fd91d32aa72f014bead569ae Mon Sep 17 00:00:00 2001
From: Tobrun
Date: Fri, 23 Feb 2018 09:43:10 +0100
Subject: [PATCH 06/24] only update the location layer accuracy when not in
RenderMode.GPS (#306)
---
.../mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 e58fc52b2..22b618c24 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
@@ -297,7 +297,7 @@ 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));
+ layerMap.get(ACCURACY_LAYER).setProperties(visibility(isStale && renderMode != RenderMode.GPS ? NONE : VISIBLE));
}
//
From 44a6602058a51fb0127d06f14d27e41fc9e28643 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Paczos?=
Date: Tue, 27 Feb 2018 16:33:00 +0100
Subject: [PATCH 07/24] Improve enabling/disabling location layer plugin (#308)
---
.../LocationLayerMapChangeActivity.java | 6 ---
.../location/LocationLayerModesActivity.java | 7 +++
app/src/main/res/menu/menu_location.xml | 9 ++++
.../plugins/locationlayer/LocationLayer.java | 6 ++-
.../locationlayer/LocationLayerAnimator.java | 49 ++++++++++---------
.../locationlayer/LocationLayerPlugin.java | 39 +++++----------
.../locationlayer/modes/RenderMode.java | 4 +-
7 files changed, 60 insertions(+), 60 deletions(-)
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 f66d93558..03c93fd82 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
@@ -65,9 +65,6 @@ public void onStyleFabClick() {
@Override
protected void onStart() {
super.onStart();
- if (locationPlugin != null) {
- locationPlugin.onStart();
- }
mapView.onStart();
}
@@ -86,9 +83,6 @@ protected void onPause() {
@Override
protected void onStop() {
super.onStop();
- if (locationPlugin != null) {
- locationPlugin.onStop();
- }
if (locationEngine != null) {
locationEngine.removeLocationUpdates();
}
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 dd327d07f..949bf45ae 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
@@ -101,6 +101,7 @@ public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
+ @SuppressLint("MissingPermission")
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (locationLayerPlugin == null) {
@@ -110,6 +111,12 @@ public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_style_change) {
toggleStyle();
return true;
+ } else if (item.getItemId() == R.id.action_plugin_disable) {
+ locationLayerPlugin.setLocationLayerEnabled(false);
+ return true;
+ } else if (item.getItemId() == R.id.action_plugin_enabled) {
+ locationLayerPlugin.setLocationLayerEnabled(true);
+ return true;
}
return super.onOptionsItemSelected(item);
diff --git a/app/src/main/res/menu/menu_location.xml b/app/src/main/res/menu/menu_location.xml
index 913d50186..eb8148819 100644
--- a/app/src/main/res/menu/menu_location.xml
+++ b/app/src/main/res/menu/menu_location.xml
@@ -4,4 +4,13 @@
+
+
+
+
+
\ No newline at end of file
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 22b618c24..860ae1ef2 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
@@ -78,10 +78,14 @@ final class LocationLayer implements LocationLayerAnimator.OnAnimationsValuesCha
LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) {
this.mapboxMap = mapboxMap;
this.context = mapView.getContext();
+ initializeComponents();
+ setRenderMode(RenderMode.NORMAL);
+ }
+
+ void initializeComponents() {
addLocationSource();
addLayers();
applyStyle(options);
- setRenderMode(RenderMode.NORMAL);
}
void applyStyle(@NonNull LocationLayerOptions options) {
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 f94d6c62b..5c7859d00 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
@@ -63,32 +63,35 @@ void feedNewCompassBearing(float previousCompassBearing, float targetCompassBear
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 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 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());
+ };
+
+ 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);
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 d917fe8fe..e36ae7b15 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
@@ -116,16 +116,16 @@ private void initialize() {
mapView.addOnMapChangedListener(this);
mapboxMap.addOnMapClickListener(this);
- compassManager = new CompassManager(mapView.getContext());
- compassManager.addCompassListener(this);
- staleStateManager = new StaleStateManager(this, options.staleStateDelay());
-
locationLayer = new LocationLayer(mapView, mapboxMap, options);
locationLayerCamera = new LocationLayerCamera(mapboxMap);
locationLayerAnimator = new LocationLayerAnimator();
locationLayerAnimator.addListener(locationLayer);
locationLayerAnimator.addListener(locationLayerCamera);
+ compassManager = new CompassManager(mapView.getContext());
+ compassManager.addCompassListener(this);
+ staleStateManager = new StaleStateManager(this, options.staleStateDelay());
+
enableLocationLayerPlugin();
}
@@ -138,23 +138,16 @@ public void setLocationLayerEnabled(boolean isEnabled) {
}
}
+ @SuppressLint("MissingPermission")
private void enableLocationLayerPlugin() {
isEnabled = true;
-
- if (locationEngine != null) {
- locationEngine.addLocationEngineListener(this);
- }
- setLastLocation();
- setLastCompassHeading();
+ onStart();
locationLayer.show();
}
private void disableLocationLayerPlugin() {
isEnabled = false;
-
- if (locationEngine != null) {
- locationEngine.removeLocationEngineListener(this);
- }
+ onStop();
locationLayer.hide();
}
@@ -204,9 +197,11 @@ public LocationLayerOptions getLocationLayerOptions() {
@Override
public void onMapChanged(int change) {
if (change == MapView.WILL_START_LOADING_MAP) {
- locationLayerAnimator.cancelAllAnimations();
+ onStop();
} else if (change == MapView.DID_FINISH_LOADING_STYLE) {
- mapStyleFinishedLoading();
+ locationLayer.initializeComponents();
+ setRenderMode(locationLayer.getRenderMode());
+ onStart();
}
}
@@ -427,18 +422,6 @@ public Location getLastKnownLocation() {
return locationEngine != null ? locationEngine.getLastLocation() : null;
}
- /**
- * If the location layer was being displayed before the style change, it will need to be displayed
- * in the new style.
- */
- @SuppressWarnings( {"MissingPermission"})
- private void mapStyleFinishedLoading() {
- // recreate runtime style components
- locationLayer = new LocationLayer(mapView, mapboxMap, options);
- setLastLocation();
- setLastCompassHeading();
- }
-
@Override
public void onCameraMove() {
CameraPosition position = mapboxMap.getCameraPosition();
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
index a7326410f..0f033c9f7 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
@@ -27,8 +27,8 @@ private RenderMode() {
* @since 0.1.0
*/
@IntDef( {COMPASS, GPS, NORMAL})
- public @Retention(RetentionPolicy.SOURCE)
- @interface Mode {
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Mode {
}
/**
From ce02ede2d2028b0da250a9233778cd712cbb038c Mon Sep 17 00:00:00 2001
From: Dan Nesfeder
Date: Tue, 27 Feb 2018 11:13:47 -0500
Subject: [PATCH 08/24] LocationLayerPlugin Javadoc (#309)
* Clean up and javadoc
* Updates per review
---
.../locationlayer/LocationLayerTest.java | 4 +-
.../locationlayer/LocationLayerOptions.java | 20 +-
.../locationlayer/LocationLayerPlugin.java | 448 +++++++++++-------
.../OnLocationStaleListener.java | 10 +
.../locationlayer/StaleStateManager.java | 2 +-
.../locationlayer/modes/CameraMode.java | 21 +-
.../locationlayer/modes/RenderMode.java | 9 +-
.../src/main/res/values/attrs.xml | 2 +-
.../src/main/res/values/styles.xml | 2 +-
9 files changed, 318 insertions(+), 200 deletions(-)
diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
index f08c4bcca..d8f98e783 100644
--- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
+++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.java
@@ -180,7 +180,7 @@ public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, Mapbo
SymbolLayer symbolLayer = mapboxMap.getLayerAs(FOREGROUND_LAYER);
assert symbolLayer != null;
assertThat(symbolLayer.getIconImage().getValue(), equalTo(FOREGROUND_ICON));
- locationLayerPlugin.applyStyle(context, LocationLayerOptions.builder(context).staleStateDelay(400).build());
+ locationLayerPlugin.applyStyle(context, LocationLayerOptions.builder(context).staleStateTimeout(400).build());
locationLayerPlugin.forceLocationUpdate(location);
uiController.loopMainThreadForAtLeast(500);
assertThat(symbolLayer.getIconImage().getValue(), equalTo(FOREGROUND_STALE_ICON));
@@ -195,7 +195,7 @@ public void whenDrawableChanged_continuesUsingStaleIcons() throws Exception {
public void onLocationLayerAction(LocationLayerPlugin locationLayerPlugin, MapboxMap mapboxMap,
UiController uiController, Context context) {
locationLayerPlugin.setLocationLayerMode(RenderMode.NORMAL);
- locationLayerPlugin.applyStyle(context, LocationLayerOptions.builder(context).staleStateDelay(100).build());
+ locationLayerPlugin.applyStyle(context, LocationLayerOptions.builder(context).staleStateTimeout(100).build());
locationLayerPlugin.forceLocationUpdate(location);
uiController.loopMainThreadForAtLeast(200);
rule.getActivity().toggleStyle();
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 9c554159f..89b071e2d 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
@@ -100,9 +100,9 @@ public static LocationLayerOptions createFromAttributes(@NonNull Context context
builder.enableStaleState(typedArray.getBoolean(
R.styleable.LocationLayer_enableStaleState, true));
}
- if (typedArray.hasValue(R.styleable.LocationLayer_staleStateDelay)) {
- builder.staleStateDelay(typedArray.getInteger(
- R.styleable.LocationLayer_staleStateDelay, (int) STALE_STATE_DELAY_MS));
+ if (typedArray.hasValue(R.styleable.LocationLayer_staleStateTimeout)) {
+ builder.staleStateTimeout(typedArray.getInteger(
+ R.styleable.LocationLayer_staleStateTimeout, (int) STALE_STATE_DELAY_MS));
}
builder.gpsDrawable(typedArray.getResourceId(
R.styleable.LocationLayer_navigationDrawable, -1));
@@ -148,7 +148,7 @@ public static Builder builder(Context context) {
private static Builder builder() {
return new AutoValue_LocationLayerOptions.Builder()
.enableStaleState(true)
- .staleStateDelay(STALE_STATE_DELAY_MS);
+ .staleStateTimeout(STALE_STATE_DELAY_MS);
}
/**
@@ -317,7 +317,7 @@ private static Builder builder() {
* @attr ref R.styleable#LocationLayer_staleStateDelay
* @since 0.4.0
*/
- public abstract long staleStateDelay();
+ public abstract long staleStateTimeout();
/**
* Builder class for constructing a new instance of {@link LocationLayerOptions}.
@@ -481,17 +481,17 @@ public abstract static class Builder {
public abstract Builder enableStaleState(boolean enabled);
/**
- * Set the delay before the location icon becomes stale. The timer begins approximately when a
+ * Set the timeout before the location icon becomes stale. The timer begins approximately when a
* new location update comes in and using this defined time, if an update hasn't occurred by the
* end, the location is considered stale.
*
- * @param delay the duration in milliseconds which it should take before the location layer is
- * considered stale
+ * @param timeout the duration in milliseconds which it should take before the location layer is
+ * considered stale
* @return this builder for chaining options together
- * @attr ref R.styleable#LocationLayer_staleStateDelay
+ * @attr ref R.styleable#LocationLayer_staleStateTimeout
* @since 0.4.0
*/
- public abstract Builder staleStateDelay(long delay);
+ public abstract Builder staleStateTimeout(long timeout);
abstract LocationLayerOptions autoBuild();
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 e36ae7b15..6a8245d08 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
@@ -32,11 +32,15 @@
* The Location layer plugin provides location awareness to your mobile application. Enabling this
* plugin provides a contextual experience to your users by showing an icon representing the users
* current location. A few different modes are offered to provide the right context to your users at
- * the correct time. {@link LocationLayerMode#NORMAL} simply shows the users location on the map
- * represented as a dot. {@link LocationLayerMode#COMPASS} mode allows you to display an arrow icon
+ * the correct time. {@link RenderMode#NORMAL} simply shows the users location on the map
+ * represented as a dot. {@link RenderMode#COMPASS} mode allows you to display an arrow icon
* (by default) that points in the direction the device is pointing in.
- * {@link LocationLayerMode#NAVIGATION} can be used in conjunction with our Navigation SDK to
- * display a larger icon we call the user puck.
+ * {@link RenderMode#GPS} can be used in conjunction with our Navigation SDK to
+ * display a larger icon (customized with {@link LocationLayerOptions#gpsDrawable()}) we call the user puck.
+ *
+ * This plugin also offers the ability to set a map camera behavior for tracking the user
+ * location. These different {@link CameraMode}s will track, stop tracking the location based on the
+ * mode set with {@link LocationLayerPlugin#setCameraMode(int)}.
*
* Lastly, {@link LocationLayerPlugin#setLocationLayerEnabled(boolean)} can be used
* to disable the Location Layer but keep the instance around till the activity is destroyed.
@@ -48,9 +52,7 @@
*
* @since 0.1.0
*/
-public final class LocationLayerPlugin implements LocationEngineListener, CompassListener,
- OnMapChangedListener, LifecycleObserver, OnCameraMoveListener, OnMapClickListener,
- OnLocationStaleListener {
+public final class LocationLayerPlugin implements LifecycleObserver {
private final MapboxMap mapboxMap;
private final MapView mapView;
@@ -72,10 +74,10 @@ public final class LocationLayerPlugin implements LocationEngineListener, Compas
= new CopyOnWriteArrayList<>();
/**
- * Construct a {@code LocationLayerPlugin}
+ * Construct a LocationLayerPlugin
*
- * @param mapView the MapView to apply the My Location layer plugin to
- * @param mapboxMap the MapboxMap to apply the My Location layer plugin with
+ * @param mapView the MapView to apply the LocationLayerPlugin to
+ * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with
* @param locationEngine the {@link LocationEngine} this plugin should use to update
* @since 0.1.0
*/
@@ -86,10 +88,10 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa
}
/**
- * Construct a {@code LocationLayerPlugin}
+ * Construct a LocationLayerPlugin
*
- * @param mapView the MapView to apply the My Location layer plugin to
- * @param mapboxMap the MapboxMap to apply the My Location layer plugin with
+ * @param mapView the MapView to apply the LocationLayerPlugin to
+ * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with
* @param locationEngine the {@link LocationEngine} this plugin should use to update
* @param styleRes customize the user location icons inside your apps {@code style.xml}
* @since 0.1.0
@@ -100,6 +102,15 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa
LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes));
}
+ /**
+ * Construct a LocationLayerPlugin
+ *
+ * @param mapView the MapView to apply the LocationLayerPlugin to
+ * @param mapboxMap the MapboxMap to apply the LocationLayerPlugin with
+ * @param locationEngine the {@link LocationEngine} this plugin should use to update
+ * @param options to customize the user location icons inside your apps
+ * @since 0.3.0
+ */
public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMap,
@Nullable LocationEngine locationEngine,
LocationLayerOptions options) {
@@ -110,26 +121,15 @@ public LocationLayerPlugin(@NonNull MapView mapView, @NonNull MapboxMap mapboxMa
initialize();
}
- private void initialize() {
- AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
-
- mapView.addOnMapChangedListener(this);
- mapboxMap.addOnMapClickListener(this);
-
- locationLayer = new LocationLayer(mapView, mapboxMap, options);
- locationLayerCamera = new LocationLayerCamera(mapboxMap);
- locationLayerAnimator = new LocationLayerAnimator();
- locationLayerAnimator.addListener(locationLayer);
- locationLayerAnimator.addListener(locationLayerCamera);
-
- compassManager = new CompassManager(mapView.getContext());
- compassManager.addCompassListener(this);
- staleStateManager = new StaleStateManager(this, options.staleStateDelay());
-
- enableLocationLayerPlugin();
- }
-
+ /**
+ * This method will show or hide the location icon and enable or disable the camera
+ * tracking the location.
+ *
+ * @param isEnabled true to show layers and enable camera, false otherwise
+ * @since 0.5.0
+ */
@RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
+
public void setLocationLayerEnabled(boolean isEnabled) {
if (isEnabled) {
enableLocationLayerPlugin();
@@ -138,109 +138,128 @@ public void setLocationLayerEnabled(boolean isEnabled) {
}
}
- @SuppressLint("MissingPermission")
- private void enableLocationLayerPlugin() {
- isEnabled = true;
- onStart();
- locationLayer.show();
- }
-
- private void disableLocationLayerPlugin() {
- isEnabled = false;
- onStop();
- locationLayer.hide();
- }
-
/**
- * 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
- * only accepts one of those modes. Note that before enabling the My Location layer, you will need
- * to ensure that you have the requested the required user location permissions.
+ * Sets the camera mode, which determines how the map camera will track the rendered location.
*
*
- *
{@link LocationLayerMode#NORMAL}: Display the user location on the map as a small dot
- *
{@link LocationLayerMode#COMPASS}: Display the user location and current heading/bearing
- *
{@link LocationLayerMode#NAVIGATION}: Display the user location on the map using a navigation icon
+ *
{@link CameraMode#NONE}: No camera tracking
+ *
{@link CameraMode#NONE_COMPASS}: Camera does not track location, but does track compass bearing
+ *
{@link CameraMode#NONE_GPS}: Camera does not track location, but does track GPS bearing
+ *
{@link CameraMode#TRACKING}: Camera tracks the user location
+ *
{@link CameraMode#TRACKING_COMPASS}: Camera tracks the user location, with bearing provided by a compass
+ *
{@link CameraMode#TRACKING_GPS}: Camera tracks the user location, with normalized bearing
+ *
{@link CameraMode#TRACKING_GPS_NORTH}: Camera tracks the user location, with bearing always set to north
*
*
- * @param locationLayerMode one of the modes found in {@link LocationLayerMode}
- * @since 0.1.0
+ * @param cameraMode one of the modes found in {@link CameraMode}
+ * @since 0.5.0
*/
public void setCameraMode(@CameraMode.Mode int cameraMode) {
locationLayerCamera.setCameraMode(cameraMode);
}
+ /**
+ * Provides the current camera mode being used to track
+ * the location or compass updates.
+ *
+ * @return the current camera mode
+ * @since 0.5.0
+ */
@CameraMode.Mode
public int getCameraMode() {
return locationLayerCamera.getCameraMode();
}
+ /**
+ * Sets the render mode, which determines how the location updates will be rendered on the map.
+ *
+ *
+ *
{@link RenderMode#NORMAL}: Shows user location, bearing ignored
+ *
{@link RenderMode#COMPASS}: Shows user location with bearing considered from compass
+ *
{@link RenderMode#GPS}: Shows user location with bearing considered from location
+ *
+ *
+ * @param renderMode one of the modes found in {@link RenderMode}
+ * @since 0.5.0
+ */
public void setRenderMode(@RenderMode.Mode int renderMode) {
locationLayer.setRenderMode(renderMode);
}
+
+ /**
+ * Provides the current render mode being used to show
+ * the location and/or compass updates on the map.
+ *
+ * @return the current render mode
+ * @since 0.5.0
+ */
@RenderMode.Mode
public int getRenderMode() {
return locationLayer.getRenderMode();
}
/**
- * Returns the current location mode being used with this plugin.
+ * Returns the current location options being used.
*
- * @return on of the {@link LocationLayerMode} values
- * @since 0.1.0
+ * @return the current {@link LocationLayerOptions}
+ * @since 0.4.0
*/
public LocationLayerOptions getLocationLayerOptions() {
return options;
}
- @Override
- public void onMapChanged(int change) {
- if (change == MapView.WILL_START_LOADING_MAP) {
- onStop();
- } else if (change == MapView.DID_FINISH_LOADING_STYLE) {
- locationLayer.initializeComponents();
- setRenderMode(locationLayer.getRenderMode());
- onStart();
- }
- }
-
- @Override
- public void onStaleStateChange(boolean isStale) {
- locationLayer.setLocationsStale(isStale);
-
- for (OnLocationStaleListener listener : onLocationStaleListeners) {
- listener.onStaleStateChange(isStale);
- }
- }
-
- public boolean isLocationStale() {
- return staleStateManager.isStale();
- }
-
/**
- * Apply a new Location Layer style after the {@link LocationLayerPlugin} has been constructed.
+ * Apply a new LocationLayer style with a style resource.
*
* @param styleRes a XML style overriding some or all the options
- * @since 0.1.0
+ * @since 0.4.0
*/
public void applyStyle(@StyleRes int styleRes) {
applyStyle(LocationLayerOptions.createFromAttributes(mapView.getContext(), styleRes));
}
+ /**
+ * Apply a new LocationLayer style with location layer options.
+ *
+ * @param options to update the current style
+ * @since 0.4.0
+ */
public void applyStyle(LocationLayerOptions options) {
locationLayer.applyStyle(options);
if (!options.enableStaleState()) {
staleStateManager.onStop();
}
- staleStateManager.setDelayTime(options.staleStateDelay());
+ staleStateManager.setDelayTime(options.staleStateTimeout());
+ }
+
+ /**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ *
+ *
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ * @since 0.5.0
+ */
+ public void setPadding(int left, int top, int right, int bottom) {
+ mapboxMap.setPadding(left, top, right, bottom);
}
/**
* Use to either force a location update or to manually control when the user location gets
* updated.
*
- * @param location where you'd like the location icon to be placed on the map
+ * @param location where the location icon is placed on the map
* @since 0.1.0
*/
public void forceLocationUpdate(@Nullable Location location) {
@@ -248,8 +267,9 @@ public void forceLocationUpdate(@Nullable Location location) {
}
/**
- * The {@link LocationEngine} the plugin will use to update it's position. If {@code null} is
- * passed in, all updates will occur through the
+ * Set the location engine to update the current user location.
+ *
+ * If {@code null} is passed in, all updates will occur through the
* {@link LocationLayerPlugin#forceLocationUpdate(Location)} method.
*
* @param locationEngine a {@link LocationEngine} this plugin should use to handle updates
@@ -260,7 +280,7 @@ public void setLocationEngine(@Nullable LocationEngine locationEngine) {
if (locationEngine != null) {
this.locationEngine = locationEngine;
} else if (this.locationEngine != null) {
- this.locationEngine.removeLocationEngineListener(this);
+ this.locationEngine.removeLocationEngineListener(locationEngineListener);
this.locationEngine = null;
}
}
@@ -282,41 +302,10 @@ public LocationEngine getLocationEngine() {
*
* @since 0.1.0
*/
- @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
- @OnLifecycleEvent(Lifecycle.Event.ON_START)
- public void onStart() {
- if (isEnabled) {
- if (locationEngine != null) {
- locationEngine.addLocationEngineListener(this);
- }
- setLastLocation();
- setLastCompassHeading();
- }
- if (mapboxMap != null) {
- mapboxMap.addOnCameraMoveListener(this);
- }
- if (options.enableStaleState()) {
- staleStateManager.onStart();
- }
- compassManager.onStart();
- }
-
- /**
- * Required to place inside your activities {@code onStop} method.
- *
- * @since 0.1.0
- */
- @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
- public void onStop() {
- staleStateManager.onStop();
- compassManager.onStop();
- locationLayerAnimator.cancelAllAnimations();
- if (locationEngine != null) {
- locationEngine.removeLocationEngineListener(this);
- }
- if (mapboxMap != null) {
- mapboxMap.removeOnCameraMoveListener(this);
- }
+ @SuppressLint("MissingPermission")
+ @Nullable
+ public Location getLastKnownLocation() {
+ return locationEngine != null ? locationEngine.getLastLocation() : null;
}
/**
@@ -327,6 +316,7 @@ public void onStop() {
* accuracy changes
* @since 0.2.0
*/
+
public void addCompassListener(@NonNull CompassListener compassListener) {
compassManager.addCompassListener(compassListener);
}
@@ -352,81 +342,112 @@ public void addOnLocationClickListener(@NonNull OnLocationLayerClickListener loc
onLocationLayerClickListeners.add(locationClickListener);
}
+ /**
+ * Removes the passed listener from the current list of location click listeners.
+ *
+ * @param locationClickListener to be removed
+ * @since 0.3.0
+ */
public void removeOnLocationClickListener(@NonNull OnLocationLayerClickListener locationClickListener) {
onLocationLayerClickListeners.remove(locationClickListener);
}
+ /**
+ * Adds the passed listener that gets invoked when user updates have stopped long enough for the last update
+ * to be considered stale.
+ *
+ * This timeout is set by {@link LocationLayerOptions#staleStateTimeout()}.
+ *
+ * @param listener invoked when last update is considered stale
+ * @since 0.5.0
+ */
public void addOnLocationStaleListener(@NonNull OnLocationStaleListener listener) {
onLocationStaleListeners.add(listener);
}
+ /**
+ * Removes the passed listener from the current list of stale listeners.
+ *
+ * @param listener to be removed from the list
+ * @since 0.5.0
+ */
public void removeOnLocationStaleListener(@NonNull OnLocationStaleListener listener) {
onLocationStaleListeners.remove(listener);
}
- @Override
- public void onMapClick(@NonNull LatLng point) {
- if (!onLocationLayerClickListeners.isEmpty() && locationLayer.onMapClick(point)) {
- for (OnLocationLayerClickListener listener : onLocationLayerClickListeners) {
- listener.onLocationLayerClick();
+ /**
+ * 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.
+ *
+ * @since 0.1.0
+ */
+ @RequiresPermission(anyOf = {ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION})
+ @OnLifecycleEvent(Lifecycle.Event.ON_START)
+ public void onStart() {
+ if (isEnabled) {
+ if (locationEngine != null) {
+ locationEngine.addLocationEngineListener(locationEngineListener);
}
+ setLastLocation();
+ setLastCompassHeading();
+ }
+ if (mapboxMap != null) {
+ mapboxMap.addOnCameraMoveListener(onCameraMoveListener);
}
+ if (options.enableStaleState()) {
+ staleStateManager.onStart();
+ }
+ compassManager.onStart();
}
- @Override
- @SuppressWarnings( {"MissingPermission"})
- public void onConnected() {
+ /**
+ * Required to place inside your activities {@code onStop} method.
+ *
+ * @since 0.4.0
+ */
+ @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
+ public void onStop() {
+ staleStateManager.onStop();
+ compassManager.onStop();
+ locationLayerAnimator.cancelAllAnimations();
if (locationEngine != null) {
- locationEngine.requestLocationUpdates();
+ locationEngine.removeLocationEngineListener(locationEngineListener);
+ }
+ if (mapboxMap != null) {
+ mapboxMap.removeOnCameraMoveListener(onCameraMoveListener);
}
}
- @Override
- public void onLocationChanged(Location location) {
- updateLocation(location);
- }
+ private void initialize() {
+ AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
- @Override
- public void onCompassChanged(float userHeading) {
- updateCompassHeading(userHeading);
- }
+ mapView.addOnMapChangedListener(onMapChangedListener);
+ mapboxMap.addOnMapClickListener(onMapClickListener);
- @Override
- public void onCompassAccuracyChange(int compassStatus) {
- // Currently don't handle this inside SDK
- }
+ locationLayer = new LocationLayer(mapView, mapboxMap, options);
+ locationLayerCamera = new LocationLayerCamera(mapboxMap);
+ locationLayerAnimator = new LocationLayerAnimator();
+ locationLayerAnimator.addListener(locationLayer);
+ locationLayerAnimator.addListener(locationLayerCamera);
- /**
- * If the locationEngine contains a last location value, we use it for the initial location layer
- * position.
- */
- @SuppressWarnings( {"MissingPermission"})
- private void setLastLocation() {
- if (locationEngine != null) {
- updateLocation(locationEngine.getLastLocation());
- }
- }
+ compassManager = new CompassManager(mapView.getContext());
+ compassManager.addCompassListener(compassListener);
+ staleStateManager = new StaleStateManager(onLocationStaleListener, options.staleStateTimeout());
- private void setLastCompassHeading() {
- updateCompassHeading(compassManager.getLastHeading());
+ enableLocationLayerPlugin();
}
- /**
- * Get the last know location of the location layer plugin.
- *
- * @return the last known location
- */
@SuppressLint("MissingPermission")
- @Nullable
- public Location getLastKnownLocation() {
- return locationEngine != null ? locationEngine.getLastLocation() : null;
+ private void enableLocationLayerPlugin() {
+ isEnabled = true;
+ onStart();
+ locationLayer.show();
}
- @Override
- public void onCameraMove() {
- CameraPosition position = mapboxMap.getCameraPosition();
- locationLayer.updateAccuracyRadius(getLastKnownLocation());
- locationLayer.updateForegroundOffset(position.tilt);
+ private void disableLocationLayerPlugin() {
+ isEnabled = false;
+ onStop();
+ locationLayer.hide();
}
/**
@@ -451,4 +472,91 @@ private void updateLocation(final Location location) {
private void updateCompassHeading(float heading) {
locationLayerAnimator.feedNewCompassBearing(compassManager.getLastHeading(), heading);
}
-}
+
+ /**
+ * If the locationEngine contains a last location value, we use it for the initial location layer
+ * position.
+ */
+ @SuppressWarnings( {"MissingPermission"})
+ private void setLastLocation() {
+ if (locationEngine != null) {
+ updateLocation(locationEngine.getLastLocation());
+ }
+ }
+
+ private void setLastCompassHeading() {
+ updateCompassHeading(compassManager.getLastHeading());
+ }
+
+ private OnCameraMoveListener onCameraMoveListener = new OnCameraMoveListener() {
+ @Override
+ public void onCameraMove() {
+ CameraPosition position = mapboxMap.getCameraPosition();
+ locationLayer.updateAccuracyRadius(getLastKnownLocation());
+ locationLayer.updateForegroundOffset(position.tilt);
+ }
+ };
+
+ private OnMapClickListener onMapClickListener = new OnMapClickListener() {
+ @Override
+ public void onMapClick(@NonNull LatLng point) {
+ if (!onLocationLayerClickListeners.isEmpty() && locationLayer.onMapClick(point)) {
+ for (OnLocationLayerClickListener listener : onLocationLayerClickListeners) {
+ listener.onLocationLayerClick();
+ }
+ }
+ }
+ };
+
+ private OnLocationStaleListener onLocationStaleListener = new OnLocationStaleListener() {
+ @Override
+ public void onStaleStateChange(boolean isStale) {
+ locationLayer.setLocationsStale(isStale);
+
+ for (OnLocationStaleListener listener : onLocationStaleListeners) {
+ listener.onStaleStateChange(isStale);
+ }
+ }
+ };
+
+ private OnMapChangedListener onMapChangedListener = new OnMapChangedListener() {
+ @SuppressLint("MissingPermission")
+ @Override
+ public void onMapChanged(int change) {
+ if (change == MapView.WILL_START_LOADING_MAP) {
+ onStop();
+ } else if (change == MapView.DID_FINISH_LOADING_STYLE) {
+ locationLayer.initializeComponents();
+ setRenderMode(locationLayer.getRenderMode());
+ onStart();
+ }
+ }
+ };
+
+ private CompassListener compassListener = new CompassListener() {
+ @Override
+ public void onCompassChanged(float userHeading) {
+ updateCompassHeading(userHeading);
+ }
+
+ @Override
+ public void onCompassAccuracyChange(int compassStatus) {
+ // Currently don't handle this inside SDK
+ }
+ };
+
+ private LocationEngineListener locationEngineListener = new LocationEngineListener() {
+ @Override
+ @SuppressWarnings( {"MissingPermission"})
+ public void onConnected() {
+ if (locationEngine != null) {
+ locationEngine.requestLocationUpdates();
+ }
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ updateLocation(location);
+ }
+ };
+}
\ No newline at end of file
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 99a1a6d2e..7389dd945 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,5 +1,15 @@
package com.mapbox.mapboxsdk.plugins.locationlayer;
+/**
+ * Listener that can be added as a callback when the last location update
+ * is considered stale.
+ *
+ * The time from the last location update that determines if a location update
+ * is stale or not is provided by {@link LocationLayerOptions#staleStateTimeout()}.
+ *
+ * @since 0.5.0
+ */
public interface OnLocationStaleListener {
+
void onStaleStateChange(boolean isStale);
}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateManager.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateManager.java
index 0d7d0af62..5558832de 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateManager.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/StaleStateManager.java
@@ -4,7 +4,7 @@
/**
* 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
+ * been updated in 'x' amount of time. {@link LocationLayerOptions#staleStateTimeout()} can be used to
* control the amount of time before the locations considered stale.
* {@link LocationLayerOptions#enableStaleState()} is available for disabling this behaviour.
*
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java
index 6672ea2e8..68692a429 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/CameraMode.java
@@ -9,9 +9,10 @@
import java.lang.annotation.RetentionPolicy;
/**
- * Contains the variety of Location Layer modes which shape the behavior of the plugin.
+ * Contains the variety of camera modes which determine how the camera will track
+ * the user location.
*
- * @since 0.1.0
+ * @since 0.5.0
*/
public final class CameraMode {
@@ -22,7 +23,7 @@ private CameraMode() {
/**
* Determine the camera tracking behavior in the {@link LocationLayerPlugin}.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
@IntDef( {NONE, NONE_COMPASS, NONE_GPS, TRACKING, TRACKING_COMPASS, TRACKING_GPS, TRACKING_GPS_NORTH})
@Retention(RetentionPolicy.SOURCE)
@@ -32,28 +33,28 @@ private CameraMode() {
/**
* No camera tracking.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int NONE = 0x00000000;
/**
* Camera does not track location, but does track compass bearing.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int NONE_COMPASS = 0x00000010;
/**
* Camera does not track location, but does track GPS {@link Location} bearing.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int NONE_GPS = 0x00000016;
/**
* Camera tracks the user location.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int TRACKING = 0x00000018;
@@ -61,7 +62,7 @@ private CameraMode() {
* Camera tracks the user location, with bearing
* provided by a compass.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int TRACKING_COMPASS = 0x00000020;
@@ -69,7 +70,7 @@ private CameraMode() {
* Camera tracks the user location, with bearing
* provided by a normalized {@link Location#getBearing()}.
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int TRACKING_GPS = 0x00000022;
@@ -78,7 +79,7 @@ private CameraMode() {
* Camera tracks the user location, with bearing
* always set to north (0).
*
- * @since 0.4.0
+ * @since 0.5.0
*/
public static final int TRACKING_GPS_NORTH = 0x00000024;
}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
index 0f033c9f7..ad5f1a047 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/modes/RenderMode.java
@@ -8,9 +8,9 @@
import java.lang.annotation.RetentionPolicy;
/**
- * Contains the variety of Location Layer modes which shape the behavior of the plugin.
+ * Contains the variety of ways the user location can be rendered on the map.
*
- * @since 0.1.0
+ * @since 0.5.0
*/
public final class RenderMode {
@@ -19,9 +19,8 @@ private RenderMode() {
}
/**
- * One of these constants should be used when
- * {@link LocationLayerPlugin#setLocationLayerMode(int)}'s called. The
- * mode can be switched at anytime by calling the {@code setLocationLayerMode} method passing
+ * One of these constants should be used with {@link LocationLayerPlugin#setRenderMode(int)}.
+ *mode can be switched at anytime by calling the {@code setLocationLayerMode} method passing
* in the new mode you'd like the location layer to be in.
*
* @since 0.1.0
diff --git a/plugin-locationlayer/src/main/res/values/attrs.xml b/plugin-locationlayer/src/main/res/values/attrs.xml
index 475feeb4e..5623ba972 100644
--- a/plugin-locationlayer/src/main/res/values/attrs.xml
+++ b/plugin-locationlayer/src/main/res/values/attrs.xml
@@ -20,7 +20,7 @@
-
+
diff --git a/plugin-locationlayer/src/main/res/values/styles.xml b/plugin-locationlayer/src/main/res/values/styles.xml
index fd67e3c18..7b17ef9ff 100644
--- a/plugin-locationlayer/src/main/res/values/styles.xml
+++ b/plugin-locationlayer/src/main/res/values/styles.xml
@@ -16,6 +16,6 @@
12dptrue
- 10000
+ 10000
\ No newline at end of file
From a5f2dc9988a141c4409b992bbed0892f2f0dcba7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Paczos?=
Date: Tue, 27 Feb 2018 19:37:56 +0100
Subject: [PATCH 09/24] LocationEngine listening to updates after resetting
(#307)
* [location-layer-plugin] - improve setting location engine
* [location-layer-plugin] - attaching location engine listener when resetting the engine
---
.../plugins/locationlayer/LocationLayerPlugin.java | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
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 6a8245d08..bfa35fcc5 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
@@ -277,12 +277,17 @@ public void forceLocationUpdate(@Nullable Location location) {
*/
@SuppressWarnings( {"MissingPermission"})
public void setLocationEngine(@Nullable LocationEngine locationEngine) {
- if (locationEngine != null) {
- this.locationEngine = locationEngine;
- } else if (this.locationEngine != null) {
+ if (this.locationEngine != null) {
this.locationEngine.removeLocationEngineListener(locationEngineListener);
this.locationEngine = null;
}
+
+ if (locationEngine != null) {
+ this.locationEngine = locationEngine;
+ if (isEnabled) {
+ this.locationEngine.addLocationEngineListener(locationEngineListener);
+ }
+ }
}
/**
From 999d19db031fde6de76bdfaad72e5a4c7223a5ac Mon Sep 17 00:00:00 2001
From: Dan Nesfeder
Date: Tue, 27 Feb 2018 13:57:32 -0500
Subject: [PATCH 10/24] Add max / min zoom and padding APIs (#313)
* Clean up and javadoc
* Add long click listener
* Add max / min zoom and padding APIs
* Fix javadoc
* Add default values to options
---
.../locationlayer/LocationLayerOptions.java | 87 +++++++++++++++++-
.../locationlayer/LocationLayerPlugin.java | 91 ++++++++++++++++---
.../OnLocationLayerClickListener.java | 1 -
.../OnLocationLayerLongClickListener.java | 13 +++
4 files changed, 179 insertions(+), 13 deletions(-)
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerLongClickListener.java
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 89b071e2d..6687f5932 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
@@ -42,6 +42,21 @@ public abstract class LocationLayerOptions implements Parcelable {
*/
private static final float ACCURACY_ALPHA_DEFAULT = 0.15f;
+ /**
+ * Default max map zoom
+ */
+ private static final float MAX_ZOOM_DEFAULT = 20;
+
+ /**
+ * Default min map zoom
+ */
+ private static final float MIN_ZOOM_DEFAULT = 2;
+
+ /**
+ * Default map padding
+ */
+ private static final int[] PADDING_DEFAULT = {0, 0, 0, 0};
+
/**
* The default value which is used when the stale state is enabled
*/
@@ -148,7 +163,10 @@ public static Builder builder(Context context) {
private static Builder builder() {
return new AutoValue_LocationLayerOptions.Builder()
.enableStaleState(true)
- .staleStateTimeout(STALE_STATE_DELAY_MS);
+ .staleStateTimeout(STALE_STATE_DELAY_MS)
+ .maxZoom(MAX_ZOOM_DEFAULT)
+ .minZoom(MIN_ZOOM_DEFAULT)
+ .padding(PADDING_DEFAULT);
}
/**
@@ -319,6 +337,40 @@ private static Builder builder() {
*/
public abstract long staleStateTimeout();
+ /**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ *
+ *
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ *
+ * @return integer array of padding values
+ * @since 0.5.0
+ */
+ @SuppressWarnings("mutable")
+ public abstract int[] padding();
+
+ /**
+ * The maximum zoom level the map can be displayed at.
+ *
+ * @return the maximum zoom level
+ * @since 0.5.0
+ */
+ public abstract double maxZoom();
+
+ /**
+ * The minimum zoom level the map can be displayed at.
+ *
+ * @return the minimum zoom level
+ * @since 0.5.0
+ */
+ public abstract double minZoom();
+
/**
* Builder class for constructing a new instance of {@link LocationLayerOptions}.
*
@@ -493,6 +545,39 @@ public abstract static class Builder {
*/
public abstract Builder staleStateTimeout(long timeout);
+ /**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ *
+ *
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ *
+ * @param padding The margins for the map in pixels (left, top, right, bottom).
+ * @since 0.5.0
+ */
+ public abstract Builder padding(int[] padding);
+
+ /**
+ * Sets the maximum zoom level the map can be displayed at.
+ *
+ * The default maximum zoomn level is 22. The upper bound for this value is 25.5.
+ *
+ * @param maxZoom The new maximum zoom level.
+ * @since 0.5.0
+ */
+ public abstract Builder maxZoom(double maxZoom);
+
+ /**
+ * Sets the minimum zoom level the map can be displayed at.
+ *
+ * @param minZoom The new minimum zoom level.
+ */
+ public abstract Builder minZoom(double minZoom);
abstract LocationLayerOptions autoBuild();
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 bfa35fcc5..15ca6c848 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
@@ -72,6 +72,8 @@ public final class LocationLayerPlugin implements LifecycleObserver {
= new CopyOnWriteArrayList<>();
private final CopyOnWriteArrayList onLocationLayerClickListeners
= new CopyOnWriteArrayList<>();
+ private final CopyOnWriteArrayList onLocationLayerLongClickListeners
+ = new CopyOnWriteArrayList<>();
/**
* Construct a LocationLayerPlugin
@@ -255,6 +257,27 @@ public void setPadding(int left, int top, int right, int bottom) {
mapboxMap.setPadding(left, top, right, bottom);
}
+ /**
+ * Sets the maximum zoom level the map can be displayed at.
+ *
+ * The default maximum zoom level is 22. The upper bound for this value is 25.5.
+ *
+ * @param maxZoom The new maximum zoom level.
+ * @since 0.5.0
+ */
+ public void setMaxZoom(double maxZoom) {
+ mapboxMap.setMaxZoomPreference(maxZoom);
+ }
+
+ /**
+ * Sets the minimum zoom level the map can be displayed at.
+ *
+ * @param minZoom The new minimum zoom level.
+ */
+ public void setMinZoom(double minZoom) {
+ mapboxMap.setMinZoomPreference(minZoom);
+ }
+
/**
* Use to either force a location update or to manually control when the user location gets
* updated.
@@ -302,9 +325,9 @@ public LocationEngine getLocationEngine() {
}
/**
- * 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.
+ * Get the last know location of the location layer plugin.
*
+ * @return the last known location
* @since 0.1.0
*/
@SuppressLint("MissingPermission")
@@ -339,22 +362,43 @@ public void removeCompassListener(@NonNull CompassListener compassListener) {
/**
* Adds a listener that gets invoked when the user clicks the location layer.
*
- * @param locationClickListener The location layer click listener that is invoked when the
- * location layer is clicked
+ * @param listener The location layer click listener that is invoked when the
+ * location layer is clicked
* @since 0.3.0
*/
- public void addOnLocationClickListener(@NonNull OnLocationLayerClickListener locationClickListener) {
- onLocationLayerClickListeners.add(locationClickListener);
+ public void addOnLocationClickListener(@NonNull OnLocationLayerClickListener listener) {
+ onLocationLayerClickListeners.add(listener);
}
/**
* Removes the passed listener from the current list of location click listeners.
*
- * @param locationClickListener to be removed
+ * @param listener to be removed
* @since 0.3.0
*/
- public void removeOnLocationClickListener(@NonNull OnLocationLayerClickListener locationClickListener) {
- onLocationLayerClickListeners.remove(locationClickListener);
+ public void removeOnLocationClickListener(@NonNull OnLocationLayerClickListener listener) {
+ onLocationLayerClickListeners.remove(listener);
+ }
+
+ /**
+ * Adds a listener that gets invoked when the user long clicks the location layer.
+ *
+ * @param listener The location layer click listener that is invoked when the
+ * location layer is clicked
+ * @since 0.5.0
+ */
+ public void addOnLocationLongClickListener(@NonNull OnLocationLayerLongClickListener listener) {
+ onLocationLayerLongClickListeners.add(listener);
+ }
+
+ /**
+ * Removes the passed listener from the current list of location long click listeners.
+ *
+ * @param listener to be removed
+ * @since 0.5.0
+ */
+ public void removeOnLocationLongClickListener(@NonNull OnLocationLayerLongClickListener listener) {
+ onLocationLayerLongClickListeners.remove(listener);
}
/**
@@ -408,7 +452,7 @@ public void onStart() {
/**
* Required to place inside your activities {@code onStop} method.
*
- * @since 0.4.0
+ * @since 0.1.0
*/
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
@@ -428,6 +472,7 @@ private void initialize() {
mapView.addOnMapChangedListener(onMapChangedListener);
mapboxMap.addOnMapClickListener(onMapClickListener);
+ updateMapWithOptions(options);
locationLayer = new LocationLayer(mapView, mapboxMap, options);
locationLayerCamera = new LocationLayerCamera(mapboxMap);
@@ -455,6 +500,19 @@ private void disableLocationLayerPlugin() {
locationLayer.hide();
}
+ private void updateMapWithOptions(LocationLayerOptions options) {
+ int[] padding = options.padding();
+ if (padding != null && padding.length == 4) {
+ setPadding(options.padding()[0], padding[1], padding[2], padding[3]);
+ }
+ if (options.maxZoom() > 0) {
+ setMaxZoom(options.maxZoom());
+ }
+ if (options.minZoom() > 0) {
+ setMinZoom(options.minZoom());
+ }
+ }
+
/**
* Updates the user location icon.
*
@@ -513,6 +571,17 @@ public void onMapClick(@NonNull LatLng point) {
}
};
+ private MapboxMap.OnMapLongClickListener onMapLongClickListener = new MapboxMap.OnMapLongClickListener() {
+ @Override
+ public void onMapLongClick(@NonNull LatLng point) {
+ if (!onLocationLayerLongClickListeners.isEmpty() && locationLayer.onMapClick(point)) {
+ for (OnLocationLayerLongClickListener listener : onLocationLayerLongClickListeners) {
+ listener.onLocationLayerLongClick();
+ }
+ }
+ }
+ };
+
private OnLocationStaleListener onLocationStaleListener = new OnLocationStaleListener() {
@Override
public void onStaleStateChange(boolean isStale) {
@@ -564,4 +633,4 @@ public void onLocationChanged(Location location) {
updateLocation(location);
}
};
-}
\ No newline at end of file
+}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerClickListener.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerClickListener.java
index ec811319b..7cfb79502 100644
--- a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerClickListener.java
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerClickListener.java
@@ -10,5 +10,4 @@
public interface OnLocationLayerClickListener {
void onLocationLayerClick();
-
}
diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerLongClickListener.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerLongClickListener.java
new file mode 100644
index 000000000..cebcf3e8d
--- /dev/null
+++ b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnLocationLayerLongClickListener.java
@@ -0,0 +1,13 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer;
+
+/**
+ * The Location Layer Plugin exposes an API for listening to when the user long clicks on the location
+ * layer icon visible on the map. when this event occurs, the {@link #onLocationLayerLongClick()} method
+ * gets invoked.
+ *
+ * @since 0.5.0
+ */
+public interface OnLocationLayerLongClickListener {
+
+ void onLocationLayerLongClick();
+}
From 62a0e1c55dccd8b34b44fa0d3ccbb66366bcf0ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Paczos?=
Date: Thu, 1 Mar 2018 18:06:52 +0100
Subject: [PATCH 11/24] Gestures logic for camera tracking, new telemetry
library (#327)
* [location-layer-plugin] - bumped maps SDK to 6.x
* [location-layer-plugin] - style options initialization fixes
* [location-layer-plugin] - added gestures handling implementation
---
.../activity/FeatureOverviewActivity.java | 4 +-
.../location/CompassListenerActivity.java | 8 +-
.../LocationLayerMapChangeActivity.java | 11 +-
.../location/LocationLayerModesActivity.java | 34 +++--
.../ManualLocationUpdatesActivity.java | 12 +-
gradle/dependencies.gradle | 2 +-
.../plugins/locationlayer/LocationLayer.java | 12 +-
.../locationlayer/LocationLayerCamera.java | 131 ++++++++++++++++--
.../locationlayer/LocationLayerOptions.java | 42 ++++++
.../locationlayer/LocationLayerPlugin.java | 52 ++++++-
.../OnCameraTrackingChangedListener.java | 21 +++
.../plugins/locationlayer/Utils.java | 21 ---
.../locationlayer/camera/MapAnimator.java | 10 +-
.../src/main/res/values/dimens.xml | 5 +
.../LocationLayerOptionsTest.java | 4 +
15 files changed, 294 insertions(+), 75 deletions(-)
create mode 100644 plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/OnCameraTrackingChangedListener.java
create mode 100644 plugin-locationlayer/src/main/res/values/dimens.xml
diff --git a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java
index 1be6e6ec5..1c8932779 100644
--- a/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java
+++ b/app/src/main/java/com/mapbox/mapboxsdk/plugins/testapp/activity/FeatureOverviewActivity.java
@@ -26,9 +26,9 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.mapbox.android.core.permissions.PermissionsListener;
+import com.mapbox.android.core.permissions.PermissionsManager;
import com.mapbox.mapboxsdk.plugins.testapp.R;
-import com.mapbox.services.android.telemetry.permissions.PermissionsListener;
-import com.mapbox.services.android.telemetry.permissions.PermissionsManager;
import java.util.ArrayList;
import java.util.Arrays;
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 fee793df4..4ad883756 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
@@ -3,17 +3,17 @@
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
+import com.mapbox.android.core.location.LocationEngine;
+import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.plugins.locationlayer.CompassListener;
-import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.testapp.R;
-import com.mapbox.services.android.location.LostLocationEngine;
-import com.mapbox.services.android.telemetry.location.LocationEngine;
import butterknife.BindView;
import butterknife.ButterKnife;
@@ -38,7 +38,7 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onMapReady(final MapboxMap mapboxMap) {
- LocationEngine locationEngine = new LostLocationEngine(this);
+ LocationEngine locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
locationLayerPlugin.setRenderMode(RenderMode.COMPASS);
locationLayerPlugin.addCompassListener(new CompassListener() {
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 03c93fd82..990f28ada 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
@@ -6,16 +6,16 @@
import android.view.Menu;
import android.view.MenuItem;
+import com.mapbox.android.core.location.LocationEngine;
+import com.mapbox.android.core.location.LocationEnginePriority;
+import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.mapboxsdk.plugins.testapp.Utils;
-import com.mapbox.services.android.location.LostLocationEngine;
-import com.mapbox.services.android.telemetry.location.LocationEngine;
-import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
import butterknife.BindView;
import butterknife.ButterKnife;
@@ -48,11 +48,12 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
- locationEngine = LostLocationEngine.getLocationEngine(this);
+ locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
locationPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
locationPlugin.setRenderMode(RenderMode.COMPASS);
+ getLifecycle().addObserver(locationPlugin);
}
@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 949bf45ae..3886af2fe 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
@@ -14,20 +14,22 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.mapbox.android.core.location.LocationEngine;
+import com.mapbox.android.core.location.LocationEngineListener;
+import com.mapbox.android.core.location.LocationEnginePriority;
+import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerOptions;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
-import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.OnCameraTrackingChangedListener;
import com.mapbox.mapboxsdk.plugins.locationlayer.OnLocationLayerClickListener;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.CameraMode;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.testapp.R;
-import com.mapbox.services.android.location.LostLocationEngine;
-import com.mapbox.services.android.telemetry.location.LocationEngine;
-import com.mapbox.services.android.telemetry.location.LocationEngineListener;
-import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
import java.util.ArrayList;
import java.util.List;
@@ -37,7 +39,7 @@
import butterknife.OnClick;
public class LocationLayerModesActivity extends AppCompatActivity implements OnMapReadyCallback,
- LocationEngineListener, OnLocationLayerClickListener {
+ LocationEngineListener, OnLocationLayerClickListener, OnCameraTrackingChangedListener {
@BindView(R.id.map_view)
MapView mapView;
@@ -86,12 +88,16 @@ public void locationModeCompass(View view) {
@Override
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
- locationEngine = new LostLocationEngine(this);
+ locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.addLocationEngineListener(this);
locationEngine.activate();
- locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine);
+ LocationLayerOptions options = LocationLayerOptions.builder(this)
+ .padding(new int[] {0, 650, 0, 0})
+ .build();
+ locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, locationEngine, options);
locationLayerPlugin.addOnLocationClickListener(this);
+ locationLayerPlugin.addOnCameraTrackingChangedListener(this);
getLifecycle().addObserver(locationLayerPlugin);
}
@@ -260,4 +266,14 @@ private void showTrackingListDialog() {
});
listPopup.show();
}
+
+ @Override
+ public void onCameraTrackingDismissed() {
+ locationTrackingBtn.setText("None");
+ }
+
+ @Override
+ public void onCameraTrackingChanged(int currentMode) {
+ // do nothing
+ }
}
\ No newline at end of file
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 8bab874b0..4ff8fb234 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
@@ -7,17 +7,17 @@
import android.support.v7.app.AppCompatActivity;
import android.view.View;
+import com.mapbox.android.core.location.LocationEngine;
+import com.mapbox.android.core.location.LocationEngineListener;
+import com.mapbox.android.core.location.LocationEnginePriority;
+import com.mapbox.android.core.location.LocationEngineProvider;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerPlugin;
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode;
import com.mapbox.mapboxsdk.plugins.testapp.R;
import com.mapbox.mapboxsdk.plugins.testapp.Utils;
-import com.mapbox.services.android.telemetry.location.LocationEngine;
-import com.mapbox.services.android.telemetry.location.LocationEngineListener;
-import com.mapbox.services.android.telemetry.location.LocationEnginePriority;
-import com.mapbox.services.android.telemetry.location.LostLocationEngine;
import butterknife.BindView;
import butterknife.ButterKnife;
@@ -66,7 +66,7 @@ public void manualLocationChangeFabClick(View view) {
@SuppressWarnings( {"MissingPermission"})
public void onMapReady(MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
- locationEngine = new LostLocationEngine(this);
+ locationEngine = new LocationEngineProvider(this).obtainBestLocationEngineAvailable();
locationEngine.addLocationEngineListener(this);
locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY);
locationEngine.activate();
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index 19871ed76..8fab159f1 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -8,7 +8,7 @@ ext {
]
version = [
- mapboxMapSdk : '5.4.0',
+ mapboxMapSdk : '6.0.0-20180301.094208-178',
mapboxGeocoding : '3.0.0-beta.2',
mapboxGeoJson : '3.0.0-beta.2',
mapboxServices : '2.2.9',
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 860ae1ef2..8cdf952c7 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
@@ -9,6 +9,9 @@
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
+import com.mapbox.geojson.Feature;
+import com.mapbox.geojson.FeatureCollection;
+import com.mapbox.geojson.Point;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -19,9 +22,6 @@
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonOptions;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
-import com.mapbox.services.commons.geojson.Feature;
-import com.mapbox.services.commons.geojson.FeatureCollection;
-import com.mapbox.services.commons.geojson.Point;
import java.util.HashMap;
import java.util.List;
@@ -78,11 +78,11 @@ final class LocationLayer implements LocationLayerAnimator.OnAnimationsValuesCha
LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) {
this.mapboxMap = mapboxMap;
this.context = mapView.getContext();
- initializeComponents();
+ initializeComponents(options);
setRenderMode(RenderMode.NORMAL);
}
- void initializeComponents() {
+ void initializeComponents(LocationLayerOptions options) {
addLocationSource();
addLayers();
applyStyle(options);
@@ -320,7 +320,7 @@ boolean onMapClick(LatLng point) {
@Override
public void onNewLatLngValue(LatLng latLng) {
- Point point = Point.fromCoordinates(new double[] {latLng.getLongitude(), latLng.getLatitude()});
+ Point point = Point.fromLngLat(latLng.getLongitude(), latLng.getLatitude());
setLocationPoint(point);
}
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 2b9f6ea22..d3d6e7a7e 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
@@ -1,35 +1,61 @@
package com.mapbox.mapboxsdk.plugins.locationlayer;
+import android.graphics.PointF;
+
+import com.mapbox.android.gestures.MoveGestureDetector;
+import com.mapbox.android.gestures.RotateGestureDetector;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
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 {
+final class LocationLayerCamera implements LocationLayerAnimator.OnAnimationsValuesChangeListener {
@CameraMode.Mode
private int cameraMode;
- private MapboxMap mapboxMap;
+ private final MapboxMap mapboxMap;
+ private final OnCameraTrackingChangedListener internalCameraTrackingChangedListener;
+ private LocationLayerOptions options;
+ private boolean adjustFocalPoint;
+
+ private final MoveGestureDetector moveGestureDetector;
- public LocationLayerCamera(MapboxMap mapboxMap) {
+ LocationLayerCamera(
+ MapboxMap mapboxMap,
+ OnCameraTrackingChangedListener internalCameraTrackingChangedListener,
+ LocationLayerOptions options) {
this.mapboxMap = mapboxMap;
+ this.internalCameraTrackingChangedListener = internalCameraTrackingChangedListener;
+ initializeOptions(options);
+
+ moveGestureDetector = mapboxMap.getGesturesManager().getMoveGestureDetector();
+ mapboxMap.addOnMoveListener(onMoveListener);
+ mapboxMap.addOnRotateListener(onRotateListener);
+ }
+
+ void initializeOptions(LocationLayerOptions options) {
+ this.options = options;
}
- public void setCameraMode(@CameraMode.Mode int cameraMode) {
+ void setCameraMode(@CameraMode.Mode int cameraMode) {
+ boolean wasTracking = isLocationTracking();
this.cameraMode = cameraMode;
mapboxMap.cancelTransitions();
+ adjustGesturesThresholds();
+ notifyCameraTrackingChangeListener(wasTracking);
}
- public int getCameraMode() {
+ int getCameraMode() {
return cameraMode;
}
private void setBearing(float bearing) {
- mapboxMap.setBearing(bearing);
+ mapboxMap.moveCamera(CameraUpdateFactory.bearingTo(bearing));
}
private void setLatLng(LatLng latLng) {
- mapboxMap.setLatLng(latLng);
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
@Override
@@ -40,6 +66,12 @@ public void onNewLatLngValue(LatLng latLng) {
|| cameraMode == CameraMode.TRACKING_GPS_NORTH) {
setLatLng(latLng);
}
+
+ if (adjustFocalPoint) {
+ PointF focalPoint = mapboxMap.getProjection().toScreenLocation(latLng);
+ mapboxMap.getUiSettings().setFocalPoint(focalPoint);
+ adjustFocalPoint = false;
+ }
}
@Override
@@ -61,9 +93,88 @@ public void onNewCompassBearingValue(float compassBearing) {
setBearing(compassBearing);
}
}
-}
+ private void adjustGesturesThresholds() {
+ if (isLocationTracking()) {
+ adjustFocalPoint = true;
+ moveGestureDetector.setMoveThreshold(options.trackingInitialMoveThreshold());
+ }
+ }
+
+ private boolean isLocationTracking() {
+ return cameraMode == CameraMode.TRACKING
+ || cameraMode == CameraMode.TRACKING_COMPASS
+ || cameraMode == CameraMode.TRACKING_GPS
+ || cameraMode == CameraMode.TRACKING_GPS_NORTH;
+ }
+
+ private boolean isBearingTracking() {
+ return cameraMode == CameraMode.NONE_COMPASS
+ || cameraMode == CameraMode.TRACKING_COMPASS
+ || cameraMode == CameraMode.NONE_GPS
+ || cameraMode == CameraMode.TRACKING_GPS
+ || cameraMode == CameraMode.TRACKING_GPS_NORTH;
+ }
+
+ private void notifyCameraTrackingChangeListener(boolean wasTracking) {
+ internalCameraTrackingChangedListener.onCameraTrackingChanged(cameraMode);
+ if (wasTracking && !isLocationTracking()) {
+ mapboxMap.getUiSettings().setFocalPoint(null);
+ moveGestureDetector.setMoveThreshold(moveGestureDetector.getDefaultMoveThreshold());
+ internalCameraTrackingChangedListener.onCameraTrackingDismissed();
+ }
+ }
+
+ private MapboxMap.OnMoveListener onMoveListener = new MapboxMap.OnMoveListener() {
+ private boolean interrupt;
+
+ @Override
+ public void onMoveBegin(MoveGestureDetector detector) {
+ if (detector.getPointersCount() > 1
+ && detector.getMoveThreshold() != options.trackingMultiFingerMoveThreshold()
+ && isLocationTracking()) {
+ detector.setMoveThreshold(options.trackingMultiFingerMoveThreshold());
+ interrupt = true;
+ }
+ }
-/*
+ @Override
+ public void onMove(MoveGestureDetector detector) {
+ if (interrupt) {
+ detector.interrupt();
+ return;
+ }
- float targetBearing = Utils.shortestRotation(0, (float) bearing);*/
+ if (isLocationTracking()) {
+ setCameraMode(CameraMode.NONE);
+ }
+ }
+
+ @Override
+ public void onMoveEnd(MoveGestureDetector detector) {
+ if (!interrupt && isLocationTracking()) {
+ moveGestureDetector.setMoveThreshold(options.trackingInitialMoveThreshold());
+ }
+ interrupt = false;
+ }
+ };
+
+ private MapboxMap.OnRotateListener onRotateListener = new MapboxMap.OnRotateListener() {
+ @Override
+ public void onRotateBegin(RotateGestureDetector detector) {
+ if (isBearingTracking()) {
+ setCameraMode(CameraMode.NONE);
+ }
+ }
+
+ @Override
+ public void onRotate(RotateGestureDetector detector) {
+ // no implementation
+ }
+
+ @Override
+ public void onRotateEnd(RotateGestureDetector detector) {
+ // no implementation
+ }
+ };
+}
\ No newline at end of file
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 6687f5932..1a6ff1427 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
@@ -129,6 +129,15 @@ public static LocationLayerOptions createFromAttributes(@NonNull Context context
R.styleable.LocationLayer_accuracyAlpha, ACCURACY_ALPHA_DEFAULT));
builder.elevation(elevation);
+ float defaultTrackingInitialMoveThreshold =
+ context.getResources().getDimension(R.dimen.mapbox_locationLayerTrackingInitialMoveThreshold);
+
+ float defaultTrackingMultiFingerMoveThreshold =
+ context.getResources().getDimension(R.dimen.mapbox_locationLayerTrackingMultiFingerMoveThreshold);
+
+ builder.trackingInitialMoveThreshold(defaultTrackingInitialMoveThreshold);
+ builder.trackingMultiFingerMoveThreshold(defaultTrackingMultiFingerMoveThreshold);
+
typedArray.recycle();
return builder.build();
@@ -371,6 +380,22 @@ private static Builder builder() {
*/
public abstract double minZoom();
+ /**
+ * Minimum single pointer movement in pixels required to break camera tracking.
+ *
+ * @return the minimum movement
+ * @since 0.5.0
+ */
+ public abstract float trackingInitialMoveThreshold();
+
+ /**
+ * Minimum multi pointer movement in pixels required to break camera tracking (for example during scale gesture).
+ *
+ * @return the minimum movement
+ * @since 0.5.0
+ */
+ public abstract float trackingMultiFingerMoveThreshold();
+
/**
* Builder class for constructing a new instance of {@link LocationLayerOptions}.
*
@@ -579,6 +604,23 @@ public abstract static class Builder {
*/
public abstract Builder minZoom(double minZoom);
+ /**
+ * Sets minimum single pointer movement (map pan) in pixels required to break camera tracking.
+ *
+ * @param moveThreshold the minimum movement
+ * @since 0.5.0
+ */
+ public abstract Builder trackingInitialMoveThreshold(float moveThreshold);
+
+ /**
+ * Sets minimum multi pointer movement (map pan) in pixels required to break camera tracking
+ * (for example during scale gesture).
+ *
+ * @param moveThreshold the minimum movement
+ * @since 0.5.0
+ */
+ public abstract Builder trackingMultiFingerMoveThreshold(float moveThreshold);
+
abstract LocationLayerOptions autoBuild();
/**
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 15ca6c848..95a3145e9 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
@@ -11,6 +11,8 @@
import android.support.annotation.StyleRes;
import android.support.v7.app.AppCompatDelegate;
+import com.mapbox.android.core.location.LocationEngine;
+import com.mapbox.android.core.location.LocationEngineListener;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -20,8 +22,6 @@
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 java.util.concurrent.CopyOnWriteArrayList;
@@ -46,7 +46,7 @@
* to disable the Location Layer but keep the instance around till the activity is destroyed.
*