From e14ed8215edb2c24ce081db4ce34934235c497cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Fri, 13 Apr 2018 15:25:45 +0200 Subject: [PATCH 1/8] [LLP] - location updates using properties --- .../plugins/locationlayer/LocationLayer.java | 62 +++++++++++++------ .../locationlayer/LocationLayerConstants.java | 2 + 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 71d463678..28863ceda 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,8 +9,9 @@ import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; +import com.google.gson.JsonObject; import com.mapbox.geojson.Feature; -import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Geometry; import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; @@ -26,6 +27,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; + +import timber.log.Timber; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_LAYER; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.BACKGROUND_ICON; @@ -37,13 +41,18 @@ 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.PROPERTY_COMPASS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_GPS_BEARING; 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; import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.getBitmapFromDrawable; import static com.mapbox.mapboxsdk.plugins.locationlayer.Utils.getDrawable; import static com.mapbox.mapboxsdk.style.expressions.Expression.exponential; +import static com.mapbox.mapboxsdk.style.expressions.Expression.get; import static com.mapbox.mapboxsdk.style.expressions.Expression.interpolate; +import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; +import static com.mapbox.mapboxsdk.style.expressions.Expression.match; import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_MAP; @@ -74,7 +83,12 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu private Context context; private final Map layerMap = new HashMap<>(); - private final Map sourceMap = new HashMap<>(); + private Feature locationFeature = Feature.fromGeometry(Point.fromLngLat(0, 0)); + private final GeoJsonSource locationSource = new GeoJsonSource( + LOCATION_SOURCE, + locationFeature, + new GeoJsonOptions().withMaxZoom(16) + ); LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) { this.mapboxMap = mapboxMap; @@ -159,7 +173,7 @@ void hide() { } } - void setLayerVisibility(String layerId, boolean visible) { + private void setLayerVisibility(String layerId, boolean visible) { layerMap.get(layerId).setProperties(visibility(visible ? VISIBLE : NONE)); } @@ -182,7 +196,15 @@ private void addSymbolLayer(String layerId, String beforeLayerId) { stop(18f, 1.2f) ) ), - iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP)); + iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP), + iconRotate( + match(literal(layerId), literal(0f), + stop(literal(FOREGROUND_LAYER), get(PROPERTY_GPS_BEARING)), + stop(literal(BACKGROUND_LAYER), get(PROPERTY_GPS_BEARING)), + stop(literal(BEARING_LAYER), get(PROPERTY_COMPASS_BEARING)) + ) + ) + ); addLayerToMap(layer, beforeLayerId); } @@ -201,8 +223,9 @@ private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) { layerMap.put(layer.getId(), layer); } - void setLayerBearing(String layerId, float bearing) { - layerMap.get(layerId).setProperties(iconRotate(bearing)); + private void setBearingProperty(String propertyId, float bearing) { + locationFeature.addNumberProperty(propertyId, bearing); + locationSource.setGeoJson(locationFeature); } void updateAccuracyRadius(Location location) { @@ -222,8 +245,9 @@ void updateForegroundOffset(double tilt) { } void updateForegroundBearing(float bearing) { - layerMap.get(FOREGROUND_LAYER).setProperties(iconRotate(bearing)); - layerMap.get(SHADOW_LAYER).setProperties(iconRotate(bearing)); +// TODO: 13.04.18 +// layerMap.get(FOREGROUND_LAYER).setProperties(iconRotate(bearing)); +// layerMap.get(SHADOW_LAYER).setProperties(iconRotate(bearing)); } private float calculateZoomLevelRadius(Location location) { @@ -240,17 +264,17 @@ private float calculateZoomLevelRadius(Location location) { // private void addLocationSource() { - FeatureCollection emptyFeature = FeatureCollection.fromFeatures(new Feature[] {}); - GeoJsonSource locationSource = new GeoJsonSource( - LOCATION_SOURCE, - emptyFeature, - new GeoJsonOptions().withMaxZoom(16)); + locationFeature.addNumberProperty(PROPERTY_GPS_BEARING, 0f); + locationFeature.addNumberProperty(PROPERTY_COMPASS_BEARING, 0f); mapboxMap.addSource(locationSource); - sourceMap.put(LOCATION_SOURCE, locationSource); } private void setLocationPoint(Point locationPoint) { - sourceMap.get(LOCATION_SOURCE).setGeoJson(locationPoint); + JsonObject properties = locationFeature.properties(); + if (properties != null) { + locationFeature = Feature.fromGeometry(locationPoint, properties); + locationSource.setGeoJson(locationFeature); + } } // @@ -290,8 +314,7 @@ private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDra layerMap.get(FOREGROUND_LAYER).setProperties( iconImage(isStale - ? FOREGROUND_STALE_ICON : FOREGROUND_ICON), - iconRotate(90f)); + ? FOREGROUND_STALE_ICON : FOREGROUND_ICON)); } private void styleForeground(@NonNull LocationLayerOptions options, boolean isStale) { @@ -344,15 +367,14 @@ public void onNewLatLngValue(LatLng latLng) { @Override public void onNewGpsBearingValue(float gpsBearing) { if (renderMode == RenderMode.GPS) { - setLayerBearing(LocationLayerConstants.FOREGROUND_LAYER, gpsBearing); - setLayerBearing(LocationLayerConstants.BACKGROUND_LAYER, gpsBearing); + setBearingProperty(PROPERTY_GPS_BEARING, gpsBearing); } } @Override public void onNewCompassBearingValue(float compassBearing) { if (renderMode == RenderMode.COMPASS) { - setLayerBearing(BEARING_LAYER, compassBearing); + setBearingProperty(PROPERTY_COMPASS_BEARING, compassBearing); } } } \ No newline at end of file diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerConstants.java index ab1a07b43..0705066d0 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 @@ -18,6 +18,8 @@ final class LocationLayerConstants { // Sources static final String LOCATION_SOURCE = "mapbox-location-source"; + static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing"; + static final String PROPERTY_COMPASS_BEARING = "mapbox-property-compass-bearing"; // Layers static final String SHADOW_LAYER = "mapbox-location-shadow"; From 5355a49ac6998ce82099d2efbc1fcb1a46a671ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Apr 2018 14:42:36 +0200 Subject: [PATCH 2/8] [LLP] using json properties to update all styling options --- .../plugins/locationlayer/LocationLayer.java | 170 ++++++++++-------- .../locationlayer/LocationLayerConstants.java | 6 + 2 files changed, 101 insertions(+), 75 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 28863ceda..f1ebea139 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,9 +9,9 @@ import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.mapbox.geojson.Feature; -import com.mapbox.geojson.Geometry; import com.mapbox.geojson.Point; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; @@ -27,9 +27,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; - -import timber.log.Timber; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.ACCURACY_LAYER; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.BACKGROUND_ICON; @@ -41,8 +38,14 @@ 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.PROPERTY_ACCURACY_ALPHA; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_ACCURACY_COLOR; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_ACCURACY_RADIUS; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_COMPASS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_FOREGROUND_ICON_OFFSET; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_GPS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_LOCATION_STALE; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_SHADOW_ICON_OFFSET; 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; @@ -54,6 +57,7 @@ import static com.mapbox.mapboxsdk.style.expressions.Expression.literal; import static com.mapbox.mapboxsdk.style.expressions.Expression.match; import static com.mapbox.mapboxsdk.style.expressions.Expression.stop; +import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase; import static com.mapbox.mapboxsdk.style.expressions.Expression.zoom; import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_MAP; import static com.mapbox.mapboxsdk.style.layers.Property.NONE; @@ -76,7 +80,6 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu @RenderMode.Mode private int renderMode; - private boolean isStale; private final MapboxMap mapboxMap; private LocationLayerOptions options; @@ -105,23 +108,15 @@ void initializeComponents(LocationLayerOptions options) { void applyStyle(@NonNull LocationLayerOptions options) { this.options = options; - styleForeground(options, isStale); float elevation = options.elevation(); // Only add icon elevation if the values greater than 0. if (elevation > 0) { - styleShadow(ContextCompat.getDrawable(context, R.drawable.mapbox_user_icon_shadow)); + styleShadow(options); } - styleForeground( - getDrawable(context, options.foregroundDrawable(), options.foregroundTintColor()), - getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor()), - isStale); - styleBackground( - getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()), - getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()), - isStale); - styleBearing( - getDrawable(context, options.bearingDrawable(), options.bearingTintColor())); + styleForeground(options); + styleBackground(options); + styleBearing(options); styleAccuracy(options.accuracyAlpha(), options.accuracyColor()); } @@ -131,14 +126,14 @@ void setRenderMode(@RenderMode.Mode int renderMode) { switch (renderMode) { case RenderMode.NORMAL: - styleForeground(options, isStale); + styleForeground(options); setLayerVisibility(SHADOW_LAYER, true); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); setLayerVisibility(ACCURACY_LAYER, true); break; case RenderMode.COMPASS: - styleForeground(options, isStale); + styleForeground(options); setLayerVisibility(SHADOW_LAYER, true); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); @@ -146,7 +141,7 @@ void setRenderMode(@RenderMode.Mode int renderMode) { setLayerVisibility(BEARING_LAYER, true); break; case RenderMode.GPS: - styleForeground(options, isStale); + styleForeground(options); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); break; @@ -168,8 +163,8 @@ void show() { } void hide() { - for (Layer layer : layerMap.values()) { - layer.setProperties(visibility(NONE)); + for (String layerId : layerMap.keySet()) { + setLayerVisibility(layerId, false); } } @@ -199,9 +194,27 @@ private void addSymbolLayer(String layerId, String beforeLayerId) { iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP), iconRotate( match(literal(layerId), literal(0f), - stop(literal(FOREGROUND_LAYER), get(PROPERTY_GPS_BEARING)), - stop(literal(BACKGROUND_LAYER), get(PROPERTY_GPS_BEARING)), - stop(literal(BEARING_LAYER), get(PROPERTY_COMPASS_BEARING)) + stop(FOREGROUND_LAYER, get(PROPERTY_GPS_BEARING)), + stop(BACKGROUND_LAYER, get(PROPERTY_GPS_BEARING)), + stop(BEARING_LAYER, get(PROPERTY_COMPASS_BEARING)) + ) + ), + iconImage( + match(literal(layerId), literal(""), + stop(FOREGROUND_LAYER, switchCase( + get(PROPERTY_LOCATION_STALE), literal(FOREGROUND_STALE_ICON), + literal(FOREGROUND_ICON))), + stop(BACKGROUND_LAYER, switchCase( + get(PROPERTY_LOCATION_STALE), literal(BACKGROUND_STALE_ICON), + literal(BACKGROUND_ICON))), + stop(SHADOW_LAYER, literal(SHADOW_ICON)), + stop(BEARING_LAYER, literal(BEARING_ICON)) + ) + ), + iconOffset( + match(literal(layerId), literal(new Float[] {0f, 0f}), + stop(literal(FOREGROUND_LAYER), get(PROPERTY_FOREGROUND_ICON_OFFSET)), + stop(literal(SHADOW_LAYER), get(PROPERTY_SHADOW_ICON_OFFSET)) ) ) ); @@ -210,7 +223,13 @@ private void addSymbolLayer(String layerId, String beforeLayerId) { private void addAccuracyLayer() { CircleLayer locationAccuracyLayer = new CircleLayer(ACCURACY_LAYER, LOCATION_SOURCE) - .withProperties(circleRadius(0f)); + .withProperties( + circleRadius(get(PROPERTY_ACCURACY_RADIUS)), + circleColor(get(PROPERTY_ACCURACY_COLOR)), + circleOpacity(get(PROPERTY_ACCURACY_ALPHA)), + circleStrokeColor(get(PROPERTY_ACCURACY_COLOR)), + circlePitchAlignment(Property.CIRCLE_PITCH_ALIGNMENT_MAP) + ); addLayerToMap(locationAccuracyLayer, BACKGROUND_LAYER); } @@ -225,31 +244,16 @@ private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) { private void setBearingProperty(String propertyId, float bearing) { locationFeature.addNumberProperty(propertyId, bearing); - locationSource.setGeoJson(locationFeature); + refreshSource(); } 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)) - ); + if (renderMode == RenderMode.COMPASS || renderMode == RenderMode.NORMAL) { + locationFeature.addNumberProperty(PROPERTY_ACCURACY_RADIUS, calculateZoomLevelRadius(location)); + refreshSource(); } } - void updateForegroundOffset(double tilt) { - layerMap.get(FOREGROUND_LAYER).setProperties( - iconOffset(new Float[] {0f, (float) (-0.05 * tilt)})); - layerMap.get(SHADOW_LAYER).setProperties( - iconOffset(new Float[] {0f, (float) (0.05 * tilt)})); - } - - void updateForegroundBearing(float bearing) { -// TODO: 13.04.18 -// layerMap.get(FOREGROUND_LAYER).setProperties(iconRotate(bearing)); -// layerMap.get(SHADOW_LAYER).setProperties(iconRotate(bearing)); - } - private float calculateZoomLevelRadius(Location location) { if (location == null) { return 0; @@ -259,6 +263,25 @@ private float calculateZoomLevelRadius(Location location) { return (float) (location.getAccuracy() * (1 / metersPerPixel)); } + void updateForegroundOffset(double tilt) { + JsonArray jsonArray = new JsonArray(); + jsonArray.add(0f); + jsonArray.add((float) (0.05 * tilt)); + locationFeature.addProperty(PROPERTY_FOREGROUND_ICON_OFFSET, jsonArray); + + jsonArray.remove(1); + jsonArray.add((float) (-0.05 * tilt)); + locationFeature.addProperty(PROPERTY_SHADOW_ICON_OFFSET, jsonArray); + + refreshSource(); + } + + void updateForegroundBearing(float bearing) { + if (renderMode != RenderMode.GPS) { + setBearingProperty(PROPERTY_GPS_BEARING, bearing); + } + } + // // Source actions // @@ -266,9 +289,14 @@ private float calculateZoomLevelRadius(Location location) { private void addLocationSource() { locationFeature.addNumberProperty(PROPERTY_GPS_BEARING, 0f); locationFeature.addNumberProperty(PROPERTY_COMPASS_BEARING, 0f); + locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, false); mapboxMap.addSource(locationSource); } + private void refreshSource() { + locationSource.setGeoJson(locationFeature); + } + private void setLocationPoint(Point locationPoint) { JsonObject properties = locationFeature.properties(); if (properties != null) { @@ -281,66 +309,58 @@ private void setLocationPoint(Point locationPoint) { // Styling // - private void styleBackground(Drawable backgroundDrawable, Drawable backgroundDrawableStale, boolean isStale) { + private void styleBackground(LocationLayerOptions options) { + Drawable backgroundDrawable = + getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()); + Drawable backgroundDrawableStale = + getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()); + mapboxMap.addImage(BACKGROUND_ICON, getBitmapFromDrawable(backgroundDrawable)); mapboxMap.addImage(BACKGROUND_STALE_ICON, getBitmapFromDrawable(backgroundDrawableStale)); - layerMap.get(BACKGROUND_LAYER).setProperties( - iconImage(isStale ? BACKGROUND_STALE_ICON : BACKGROUND_ICON)); } - private void styleShadow(Drawable shadowDrawable) { + private void styleShadow(LocationLayerOptions options) { + Drawable shadowDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_user_icon_shadow); mapboxMap.addImage(SHADOW_ICON, generateShadow(shadowDrawable, options.elevation())); - layerMap.get(SHADOW_LAYER).setProperties(iconImage(SHADOW_ICON)); } - private void styleBearing(Drawable bearingDrawable) { + private void styleBearing(LocationLayerOptions options) { + Drawable bearingDrawable = getDrawable(context, options.bearingDrawable(), options.bearingTintColor()); mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable)); - layerMap.get(BEARING_LAYER).setProperties( - iconImage(BEARING_ICON)); } private void styleAccuracy(float accuracyAlpha, @ColorInt int accuracyColor) { - layerMap.get(ACCURACY_LAYER).setProperties( - circleColor(accuracyColor), - circleOpacity(accuracyAlpha), - circlePitchAlignment(Property.CIRCLE_PITCH_ALIGNMENT_MAP), - circleStrokeColor(accuracyColor) - ); + locationFeature.addNumberProperty(PROPERTY_ACCURACY_ALPHA, accuracyAlpha); + locationFeature.addNumberProperty(PROPERTY_ACCURACY_COLOR, accuracyColor); + refreshSource(); } - private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale, boolean isStale) { + private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale) { 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)); } - private void styleForeground(@NonNull LocationLayerOptions options, boolean isStale) { + private void styleForeground(@NonNull LocationLayerOptions options) { if (renderMode == RenderMode.GPS) { - styleForegroundGPS(isStale); + styleForegroundGPS(options); } else { styleForeground( getDrawable(context, options.foregroundDrawable(), options.foregroundTintColor()), - getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor()), - isStale); + getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor())); } } - private void styleForegroundGPS(boolean isStale) { + private void styleForegroundGPS(LocationLayerOptions options) { styleForeground( getDrawable(context, options.gpsDrawable(), options.foregroundTintColor()), - getDrawable(context, options.gpsDrawable(), options.foregroundStaleTintColor()), - isStale); + getDrawable(context, options.gpsDrawable(), options.foregroundStaleTintColor())); } 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)); + locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, isStale); + refreshSource(); if (renderMode != RenderMode.GPS) { - layerMap.get(ACCURACY_LAYER).setProperties(visibility(isStale ? NONE : VISIBLE)); + setLayerVisibility(ACCURACY_LAYER, !isStale); } } 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 0705066d0..71a5fc398 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 @@ -20,6 +20,12 @@ final class LocationLayerConstants { static final String LOCATION_SOURCE = "mapbox-location-source"; static final String PROPERTY_GPS_BEARING = "mapbox-property-gps-bearing"; static final String PROPERTY_COMPASS_BEARING = "mapbox-property-compass-bearing"; + static final String PROPERTY_LOCATION_STALE = "mapbox-property-location-stale"; + static final String PROPERTY_ACCURACY_RADIUS = "mapbox-property-accuracy-radius"; + static final String PROPERTY_ACCURACY_COLOR = "mapbox-property-accuracy-color"; + static final String PROPERTY_ACCURACY_ALPHA = "mapbox-property-accuracy-alpha"; + static final String PROPERTY_FOREGROUND_ICON_OFFSET = "mapbox-property-foreground-icon-offset"; + static final String PROPERTY_SHADOW_ICON_OFFSET = "mapbox-property-shadow-icon-offset"; // Layers static final String SHADOW_LAYER = "mapbox-location-shadow"; From 05bb5e76ba209523cafecc44663fe94a1baf54b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Apr 2018 15:58:48 +0200 Subject: [PATCH 3/8] [LLP] - optimized layer updates --- .../plugins/locationlayer/LocationLayer.java | 18 ++++++++++-------- .../locationlayer/LocationLayerPlugin.java | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index f1ebea139..44b86873d 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 @@ -196,6 +196,7 @@ private void addSymbolLayer(String layerId, String beforeLayerId) { match(literal(layerId), literal(0f), stop(FOREGROUND_LAYER, get(PROPERTY_GPS_BEARING)), stop(BACKGROUND_LAYER, get(PROPERTY_GPS_BEARING)), + stop(SHADOW_LAYER, get(PROPERTY_GPS_BEARING)), stop(BEARING_LAYER, get(PROPERTY_COMPASS_BEARING)) ) ), @@ -264,14 +265,15 @@ private float calculateZoomLevelRadius(Location location) { } void updateForegroundOffset(double tilt) { - JsonArray jsonArray = new JsonArray(); - jsonArray.add(0f); - jsonArray.add((float) (0.05 * tilt)); - locationFeature.addProperty(PROPERTY_FOREGROUND_ICON_OFFSET, jsonArray); - - jsonArray.remove(1); - jsonArray.add((float) (-0.05 * tilt)); - locationFeature.addProperty(PROPERTY_SHADOW_ICON_OFFSET, jsonArray); + JsonArray foregroundJsonArray = new JsonArray(); + foregroundJsonArray.add(0f); + foregroundJsonArray.add((float) (-0.05 * tilt)); + locationFeature.addProperty(PROPERTY_FOREGROUND_ICON_OFFSET, foregroundJsonArray); + + JsonArray backgroundJsonArray = new JsonArray(); + backgroundJsonArray.add(0f); + backgroundJsonArray.add((float) (0.05 * tilt)); + locationFeature.addProperty(PROPERTY_SHADOW_ICON_OFFSET, backgroundJsonArray); refreshSource(); } 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 912949f48..4b3ffb948 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 @@ -485,7 +485,7 @@ private void disableLocationLayerPlugin() { private void updateMapWithOptions(final LocationLayerOptions options) { mapboxMap.setPadding( - options.padding()[0], options.padding()[1],options.padding()[2], options.padding()[3] + options.padding()[0], options.padding()[1], options.padding()[2], options.padding()[3] ); mapboxMap.setMaxZoomPreference(options.maxZoom()); @@ -535,11 +535,23 @@ private void setLastCompassHeading() { @Override public void onCameraMove() { CameraPosition position = mapboxMap.getCameraPosition(); - if (position.equals(lastCameraPosition)) { - locationLayer.updateAccuracyRadius(getLastKnownLocation()); + if (lastCameraPosition == null) { + lastCameraPosition = position; + locationLayer.updateForegroundBearing((float) position.bearing); locationLayer.updateForegroundOffset(position.tilt); + locationLayer.updateAccuracyRadius(getLastKnownLocation()); + return; + } + + if (position.bearing != lastCameraPosition.bearing) { locationLayer.updateForegroundBearing((float) position.bearing); } + if (position.tilt != lastCameraPosition.tilt) { + locationLayer.updateForegroundOffset(position.tilt); + } + if (position.zoom != lastCameraPosition.zoom) { + locationLayer.updateAccuracyRadius(getLastKnownLocation()); + } lastCameraPosition = position; } }; From 94cc8e1b595f342d50299c20084187654ea92717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 16 Apr 2018 18:07:43 +0200 Subject: [PATCH 4/8] [LLP] - recreate source after style is reloaded --- .../plugins/locationlayer/LocationLayer.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 44b86873d..7f199380c 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 @@ -87,11 +87,7 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu private final Map layerMap = new HashMap<>(); private Feature locationFeature = Feature.fromGeometry(Point.fromLngLat(0, 0)); - private final GeoJsonSource locationSource = new GeoJsonSource( - LOCATION_SOURCE, - locationFeature, - new GeoJsonOptions().withMaxZoom(16) - ); + private GeoJsonSource locationSource; LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) { this.mapboxMap = mapboxMap; @@ -291,7 +287,14 @@ void updateForegroundBearing(float bearing) { private void addLocationSource() { locationFeature.addNumberProperty(PROPERTY_GPS_BEARING, 0f); locationFeature.addNumberProperty(PROPERTY_COMPASS_BEARING, 0f); - locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, false); + locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, true); + + locationSource = new GeoJsonSource( + LOCATION_SOURCE, + locationFeature, + new GeoJsonOptions().withMaxZoom(16) + ); + mapboxMap.addSource(locationSource); } From db0065d678bd9a2f9d4bc7fcbc4ce446523f4056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Tue, 17 Apr 2018 11:19:35 +0200 Subject: [PATCH 5/8] [LLP] - initialize in a not stale state --- .../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 7f199380c..f4d4e5e64 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 @@ -287,7 +287,7 @@ void updateForegroundBearing(float bearing) { private void addLocationSource() { locationFeature.addNumberProperty(PROPERTY_GPS_BEARING, 0f); locationFeature.addNumberProperty(PROPERTY_COMPASS_BEARING, 0f); - locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, true); + locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, false); locationSource = new GeoJsonSource( LOCATION_SOURCE, From 94b7483ff8425dba993beedf3ce1819bea3c8255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 19 Apr 2018 10:43:30 +0200 Subject: [PATCH 6/8] [LLP] - add location source only with first sample --- .../plugins/locationlayer/LocationLayer.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index f4d4e5e64..084bb888a 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 @@ -88,6 +88,7 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu private final Map layerMap = new HashMap<>(); private Feature locationFeature = Feature.fromGeometry(Point.fromLngLat(0, 0)); private GeoJsonSource locationSource; + private boolean isSourceInitialized; LocationLayer(MapView mapView, MapboxMap mapboxMap, LocationLayerOptions options) { this.mapboxMap = mapboxMap; @@ -97,7 +98,7 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu } void initializeComponents(LocationLayerOptions options) { - addLocationSource(); + prepareLocationSource(); addLayers(); applyStyle(options); } @@ -284,7 +285,7 @@ void updateForegroundBearing(float bearing) { // Source actions // - private void addLocationSource() { + private void prepareLocationSource() { locationFeature.addNumberProperty(PROPERTY_GPS_BEARING, 0f); locationFeature.addNumberProperty(PROPERTY_COMPASS_BEARING, 0f); locationFeature.addBooleanProperty(PROPERTY_LOCATION_STALE, false); @@ -294,8 +295,11 @@ private void addLocationSource() { locationFeature, new GeoJsonOptions().withMaxZoom(16) ); + } + private void addLocationSource() { mapboxMap.addSource(locationSource); + isSourceInitialized = true; } private void refreshSource() { @@ -308,6 +312,10 @@ private void setLocationPoint(Point locationPoint) { locationFeature = Feature.fromGeometry(locationPoint, properties); locationSource.setGeoJson(locationFeature); } + + if (!isSourceInitialized) { + addLocationSource(); + } } // From 5fa8cfe5324bda9aca161a42b739040f23e69257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 19 Apr 2018 10:56:22 +0200 Subject: [PATCH 7/8] [LLP] - update layer offsets when changing render mode --- .../locationlayer/LocationLayerPlugin.java | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 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 4b3ffb948..b9baf7884 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 @@ -65,6 +65,8 @@ public final class LocationLayerPlugin implements LifecycleObserver { private LocationLayerAnimator locationLayerAnimator; + private CameraPosition lastCameraPosition; + private boolean isEnabled; private StaleStateManager staleStateManager; private final CopyOnWriteArrayList onLocationStaleListeners @@ -189,6 +191,7 @@ public int getCameraMode() { */ public void setRenderMode(@RenderMode.Mode int renderMode) { locationLayer.setRenderMode(renderMode); + updateLayerOffsets(true); } /** @@ -528,31 +531,33 @@ private void setLastCompassHeading() { updateCompassHeading(compassManager.getLastHeading()); } - private OnCameraMoveListener onCameraMoveListener = new OnCameraMoveListener() { + private void updateLayerOffsets(boolean forceUpdate) { + CameraPosition position = mapboxMap.getCameraPosition(); + if (lastCameraPosition == null || forceUpdate) { + lastCameraPosition = position; + locationLayer.updateForegroundBearing((float) position.bearing); + locationLayer.updateForegroundOffset(position.tilt); + locationLayer.updateAccuracyRadius(getLastKnownLocation()); + return; + } - private CameraPosition lastCameraPosition; + if (position.bearing != lastCameraPosition.bearing) { + locationLayer.updateForegroundBearing((float) position.bearing); + } + if (position.tilt != lastCameraPosition.tilt) { + locationLayer.updateForegroundOffset(position.tilt); + } + if (position.zoom != lastCameraPosition.zoom) { + locationLayer.updateAccuracyRadius(getLastKnownLocation()); + } + lastCameraPosition = position; + } + + private OnCameraMoveListener onCameraMoveListener = new OnCameraMoveListener() { @Override public void onCameraMove() { - CameraPosition position = mapboxMap.getCameraPosition(); - if (lastCameraPosition == null) { - lastCameraPosition = position; - locationLayer.updateForegroundBearing((float) position.bearing); - locationLayer.updateForegroundOffset(position.tilt); - locationLayer.updateAccuracyRadius(getLastKnownLocation()); - return; - } - - if (position.bearing != lastCameraPosition.bearing) { - locationLayer.updateForegroundBearing((float) position.bearing); - } - if (position.tilt != lastCameraPosition.tilt) { - locationLayer.updateForegroundOffset(position.tilt); - } - if (position.zoom != lastCameraPosition.zoom) { - locationLayer.updateAccuracyRadius(getLastKnownLocation()); - } - lastCameraPosition = position; + updateLayerOffsets(false); } }; From 493a969241cf670ccc51d4b807e597d83261d801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 19 Apr 2018 11:12:19 +0200 Subject: [PATCH 8/8] [LLP] - updating layer visibility improvements --- .../plugins/locationlayer/LocationLayer.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java b/plugin-locationlayer/src/main/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayer.java index 084bb888a..aac2e8a9d 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 @@ -119,7 +119,7 @@ void applyStyle(@NonNull LocationLayerOptions options) { void setRenderMode(@RenderMode.Mode int renderMode) { this.renderMode = renderMode; - hide(); + boolean isStale = locationFeature.getBooleanProperty(PROPERTY_LOCATION_STALE); switch (renderMode) { case RenderMode.NORMAL: @@ -127,20 +127,24 @@ void setRenderMode(@RenderMode.Mode int renderMode) { setLayerVisibility(SHADOW_LAYER, true); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); - setLayerVisibility(ACCURACY_LAYER, true); + setLayerVisibility(ACCURACY_LAYER, !isStale); + setLayerVisibility(BEARING_LAYER, false); break; case RenderMode.COMPASS: styleForeground(options); setLayerVisibility(SHADOW_LAYER, true); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); - setLayerVisibility(ACCURACY_LAYER, true); + setLayerVisibility(ACCURACY_LAYER, !isStale); setLayerVisibility(BEARING_LAYER, true); break; case RenderMode.GPS: styleForeground(options); + setLayerVisibility(SHADOW_LAYER, false); setLayerVisibility(FOREGROUND_LAYER, true); setLayerVisibility(BACKGROUND_LAYER, true); + setLayerVisibility(ACCURACY_LAYER, false); + setLayerVisibility(BEARING_LAYER, false); break; default: break; @@ -166,7 +170,11 @@ void hide() { } private void setLayerVisibility(String layerId, boolean visible) { - layerMap.get(layerId).setProperties(visibility(visible ? VISIBLE : NONE)); + Layer layer = layerMap.get(layerId); + String targetVisibility = visible ? VISIBLE : NONE; + if (!layer.getVisibility().value.equals(targetVisibility)) { + layer.setProperties(visibility(visible ? VISIBLE : NONE)); + } } private void addLayers() {