From 95010fc1c8e9db3554c0cd5d2a6719a351da836e Mon Sep 17 00:00:00 2001 From: danesfeder Date: Thu, 5 Jul 2018 16:36:43 -0400 Subject: [PATCH 1/2] Allow pre-loaded MapboxMap images / maki icons in LocationLayerOptions --- .../locationlayer/LocationLayerPluginTest.kt | 50 +++++ .../plugins/utils/MapboxTestingUtils.kt | 19 ++ app/src/main/res/values/styles.xml | 2 +- .../plugins/locationlayer/LocationLayer.java | 107 +++++----- .../locationlayer/LocationLayerOptions.java | 187 +++++++++++++++++- .../src/main/res/values/attrs.xml | 2 +- .../src/main/res/values/styles.xml | 2 +- 7 files changed, 319 insertions(+), 50 deletions(-) diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index da1dc9d7b..1c1c570a5 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -16,6 +16,7 @@ import android.support.test.filters.LargeTest import android.support.test.rule.ActivityTestRule import android.support.test.rule.GrantPermissionRule import android.support.test.runner.AndroidJUnit4 +import android.support.v4.content.ContextCompat import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.constants.Style import com.mapbox.mapboxsdk.geometry.LatLng @@ -31,7 +32,9 @@ import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourc import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.style.layers.PropertyFactory +import com.mapbox.mapboxsdk.style.layers.SymbolLayer import com.mapbox.mapboxsdk.style.sources.GeoJsonSource +import junit.framework.Assert.assertTrue import org.hamcrest.CoreMatchers.* import org.junit.After import org.junit.Assert.assertEquals @@ -192,6 +195,53 @@ class LocationLayerPluginTest { PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) } + @Test + fun locationLayerOptions_loadsForegroundBitmapFromNameOption() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) + + val foregroundLayer = mapboxMap.getLayer(FOREGROUND_LAYER) as SymbolLayer + val iconImageValue = foregroundLayer.iconImage.expression.toString() + + assertTrue(iconImageValue.contains("custom-foreground-bitmap")) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_loadsGpsNameWithGpsRenderMode() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) + mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) + mapboxMap.addImageFromDrawable("custom-gps-bitmap", foregroundDrawable) + + val foregroundLayer = mapboxMap.getLayer(FOREGROUND_LAYER) as SymbolLayer + val iconImageValue = foregroundLayer.iconImage.expression.toString() + + assertTrue(iconImageValue.contains("custom-gps-bitmap")) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) + } + @Test fun stillStaleAfterResuming() { val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt index 459491a68..a44c37a1e 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt @@ -1,5 +1,9 @@ package com.mapbox.mapboxsdk.plugins.utils +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable import android.os.Handler import android.os.Looper import com.mapbox.geojson.Feature @@ -49,4 +53,19 @@ class MapboxTestingUtils { } } } +} + +fun MapboxMap.addImageFromDrawable(string: String, drawable: Drawable) { + val bitmapFromDrawable = getBitmapFromDrawable(drawable) + this.addImage(string, bitmapFromDrawable) +} + +private fun getBitmapFromDrawable(drawable: Drawable): Bitmap { + if (drawable is BitmapDrawable) return drawable.bitmap + val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, + drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + return bitmap } \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index dac5eebbd..54be5f557 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -14,7 +14,7 @@ @drawable/custom_user_icon @drawable/custom_user_arrow - @drawable/custom_user_puck_icon + @drawable/custom_user_puck_icon 0.15 #FF82C6 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 7d689b5b8..35881c6ae 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 @@ -103,7 +103,7 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu void initializeComponents(LocationLayerOptions options) { addLocationSource(); - addLayers(); + addLayers(options); applyStyle(options); if (isHidden) { @@ -192,15 +192,22 @@ private void setLayerVisibility(String layerId, boolean visible) { } } - private void addLayers() { - addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER); - addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER); - addSymbolLayer(FOREGROUND_LAYER, null); - addSymbolLayer(BEARING_LAYER, null); + private void addLayers(LocationLayerOptions options) { + addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER, options); + addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER, options); + addSymbolLayer(FOREGROUND_LAYER, null, options); + addSymbolLayer(BEARING_LAYER, null, options); addAccuracyLayer(); } - private void addSymbolLayer(String layerId, String beforeLayerId) { + private void addSymbolLayer(String layerId, String beforeLayerId, LocationLayerOptions options) { + String foregroundString = options.gpsName() != null ? options.gpsName() : options.foregroundName(); + String foregroundIconString = buildIconString(foregroundString, FOREGROUND_ICON); + String foregroundStaleIconString = buildIconString(options.foregroundStaleName(), FOREGROUND_STALE_ICON); + String backgroundIconString = buildIconString(options.backgroundName(), BACKGROUND_ICON); + String backgroundStaleIconString = buildIconString(options.backgroundStaleName(), BACKGROUND_STALE_ICON); + String bearingIconString = buildIconString(options.bearingName(), BEARING_ICON); + SymbolLayer layer = new SymbolLayer(layerId, LOCATION_SOURCE); layer.setProperties( iconAllowOverlap(true), @@ -217,13 +224,13 @@ private void addSymbolLayer(String layerId, String beforeLayerId) { iconImage( match(literal(layerId), literal(""), stop(FOREGROUND_LAYER, switchCase( - get(PROPERTY_LOCATION_STALE), literal(FOREGROUND_STALE_ICON), - literal(FOREGROUND_ICON))), + get(PROPERTY_LOCATION_STALE), literal(foregroundStaleIconString), + literal(foregroundIconString))), stop(BACKGROUND_LAYER, switchCase( - get(PROPERTY_LOCATION_STALE), literal(BACKGROUND_STALE_ICON), - literal(BACKGROUND_ICON))), + get(PROPERTY_LOCATION_STALE), literal(backgroundStaleIconString), + literal(backgroundIconString))), stop(SHADOW_LAYER, literal(SHADOW_ICON)), - stop(BEARING_LAYER, literal(BEARING_ICON)) + stop(BEARING_LAYER, literal(bearingIconString)) ) ), iconOffset( @@ -257,6 +264,13 @@ private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) { layerMap.add(layer.getId()); } + private String buildIconString(String bitmapName, @NonNull String drawableName) { + if (bitmapName != null) { + return bitmapName; + } + return drawableName; + } + private void setBearingProperty(String propertyId, float bearing) { locationFeature.addNumberProperty(propertyId, bearing); refreshSource(); @@ -334,14 +348,45 @@ private void setLocationPoint(Point locationPoint) { // Styling // + private void styleForeground(@NonNull LocationLayerOptions options) { + boolean isGpsRenderMode = renderMode == RenderMode.GPS; + // GPS name will cover both foreground & foreground stale + if (isGpsRenderMode && options.gpsName() != null) { + return; + } + + if (options.foregroundName() == null) { + int foregroundDrawableResId = isGpsRenderMode ? options.gpsDrawable() : options.foregroundDrawable(); + Drawable foregroundDrawable = getDrawable( + context, foregroundDrawableResId, options.foregroundTintColor()); + mapboxMap.addImage(FOREGROUND_ICON, getBitmapFromDrawable(foregroundDrawable)); + } + if (options.foregroundStaleName() == null) { + int foregroundDrawableResId = isGpsRenderMode ? options.gpsDrawable() : options.foregroundDrawableStale(); + Drawable foregroundDrawableStale = getDrawable( + context, foregroundDrawableResId, options.foregroundStaleTintColor()); + mapboxMap.addImage(FOREGROUND_STALE_ICON, getBitmapFromDrawable(foregroundDrawableStale)); + } + } + private void styleBackground(LocationLayerOptions options) { - Drawable backgroundDrawable = - getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()); - Drawable backgroundDrawableStale = - getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()); + if (options.backgroundName() == null) { + Drawable backgroundDrawable = + getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()); + mapboxMap.addImage(BACKGROUND_ICON, getBitmapFromDrawable(backgroundDrawable)); + } + if (options.backgroundStaleName() == null) { + Drawable backgroundDrawableStale = + getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()); + mapboxMap.addImage(BACKGROUND_STALE_ICON, getBitmapFromDrawable(backgroundDrawableStale)); + } + } - mapboxMap.addImage(BACKGROUND_ICON, getBitmapFromDrawable(backgroundDrawable)); - mapboxMap.addImage(BACKGROUND_STALE_ICON, getBitmapFromDrawable(backgroundDrawableStale)); + private void styleBearing(LocationLayerOptions options) { + if (options.bearingName() == null) { + Drawable bearingDrawable = getDrawable(context, options.bearingDrawable(), options.bearingTintColor()); + mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable)); + } } private void styleShadow(LocationLayerOptions options) { @@ -349,38 +394,12 @@ private void styleShadow(LocationLayerOptions options) { mapboxMap.addImage(SHADOW_ICON, generateShadow(shadowDrawable, options.elevation())); } - private void styleBearing(LocationLayerOptions options) { - Drawable bearingDrawable = getDrawable(context, options.bearingDrawable(), options.bearingTintColor()); - mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable)); - } - private void styleAccuracy(float accuracyAlpha, @ColorInt int accuracyColor) { locationFeature.addNumberProperty(PROPERTY_ACCURACY_ALPHA, accuracyAlpha); locationFeature.addStringProperty(PROPERTY_ACCURACY_COLOR, colorToRgbaString(accuracyColor)); refreshSource(); } - private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale) { - mapboxMap.addImage(FOREGROUND_ICON, getBitmapFromDrawable(foregroundDrawable)); - mapboxMap.addImage(FOREGROUND_STALE_ICON, getBitmapFromDrawable(foregroundDrawableStale)); - } - - private void styleForeground(@NonNull LocationLayerOptions options) { - if (renderMode == RenderMode.GPS) { - styleForegroundGPS(options); - } else { - styleForeground( - getDrawable(context, options.foregroundDrawable(), options.foregroundTintColor()), - getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor())); - } - } - - private void styleForegroundGPS(LocationLayerOptions options) { - styleForeground( - getDrawable(context, options.gpsDrawable(), options.foregroundTintColor()), - getDrawable(context, options.gpsDrawable(), options.foregroundStaleTintColor())); - } - private void styleScaling(LocationLayerOptions options) { for (String layerId : layerMap) { Layer layer = mapboxMap.getLayer(layerId); 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 c203de754..f681626f3 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 @@ -2,6 +2,7 @@ import android.content.Context; import android.content.res.TypedArray; +import android.graphics.Bitmap; import android.os.Parcelable; import android.support.annotation.ColorInt; import android.support.annotation.Dimension; @@ -131,7 +132,7 @@ public static LocationLayerOptions createFromAttributes(@NonNull Context context R.styleable.mapbox_LocationLayer_mapbox_staleStateTimeout, (int) STALE_STATE_DELAY_MS)); } builder.gpsDrawable(typedArray.getResourceId( - R.styleable.mapbox_LocationLayer_mapbox_navigationDrawable, -1)); + R.styleable.mapbox_LocationLayer_mapbox_gpsDrawable, -1)); float elevation = typedArray.getDimension( R.styleable.mapbox_LocationLayer_mapbox_elevation, 0); builder.accuracyColor(typedArray.getColor( @@ -252,6 +253,21 @@ private static Builder builder() { @DrawableRes public abstract int backgroundDrawableStale(); + /** + * String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_foregroundDrawableStale. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @return String icon or maki-icon name + * @since 0.6.0 + */ + @Nullable + public abstract String backgroundStaleName(); + /** * Defines the drawable used for the stale foreground icon. * @@ -262,16 +278,46 @@ private static Builder builder() { @DrawableRes public abstract int foregroundDrawableStale(); + /** + * String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_foregroundDrawableStale. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @return String icon or maki-icon name + * @since 0.6.0 + */ + @Nullable + public abstract String foregroundStaleName(); + /** * Defines the drawable used for the navigation state icon. * * @return the drawable resource ID - * @attr ref R.styleable#LocationLayer_navigationDrawable + * @attr ref R.styleable#LocationLayer_gpsDrawable * @since 0.4.0 */ @DrawableRes public abstract int gpsDrawable(); + /** + * String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_gpsDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @return String icon or maki-icon name + * @since 0.6.0 + */ + @Nullable + public abstract String gpsName(); + /** * Supply a Drawable that is to be rendered on top of all of the content in the Location Layer * Plugin layer stack. @@ -283,6 +329,21 @@ private static Builder builder() { @DrawableRes public abstract int foregroundDrawable(); + /** + * String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_foregroundDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @return String icon or maki-icon name + * @since 0.6.0 + */ + @Nullable + public abstract String foregroundName(); + /** * Defines the drawable used for the background state icon. * @@ -293,6 +354,21 @@ private static Builder builder() { @DrawableRes public abstract int backgroundDrawable(); + /** + * String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_backgroundDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @return String icon or maki-icon name + * @since 0.6.0 + */ + @Nullable + public abstract String backgroundName(); + /** * Defines the drawable used for the bearing icon. * @@ -303,6 +379,21 @@ private static Builder builder() { @DrawableRes public abstract int bearingDrawable(); + /** + * String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_bearingDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @return String icon or maki-icon name + * @since 0.6.0 + */ + @Nullable + public abstract String bearingName(); + /** * Defines the bearing icon color as an integer. * @@ -497,6 +588,21 @@ public abstract static class Builder { */ public abstract Builder foregroundDrawableStale(@DrawableRes int foregroundDrawableStale); + /** + * Given a String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_foregroundDrawableStale. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @param foregroundStaleName String icon or maki-icon name + * @return this builder for chaining options together + * @since 0.6.0 + */ + public abstract Builder foregroundStaleName(@Nullable String foregroundStaleName); + /** * Defines the foreground stale color as an integer. * @@ -517,6 +623,21 @@ public abstract static class Builder { */ public abstract Builder backgroundDrawableStale(@DrawableRes int backgroundDrawableStale); + /** + * Given a String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_backgroundDrawableStale. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @param backgroundStaleName String icon or maki-icon name + * @return this builder for chaining options together + * @since 0.6.0 + */ + public abstract Builder backgroundStaleName(@Nullable String backgroundStaleName); + /** * Defines the background stale color as an integer. * @@ -532,11 +653,26 @@ public abstract static class Builder { * * @param gpsDrawable the drawable resource ID * @return this builder for chaining options together - * @attr ref R.styleable#LocationLayer_navigationDrawable + * @attr ref R.styleable#LocationLayer_gpsDrawable * @since 0.4.0 */ public abstract Builder gpsDrawable(@DrawableRes int gpsDrawable); + /** + * Given a String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_gpsDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @param gpsName String icon or maki-icon name + * @return this builder for chaining options together + * @since 0.6.0 + */ + public abstract Builder gpsName(@Nullable String gpsName); + /** * Supply a Drawable that is to be rendered on top of all of the content in the Location Layer * Plugin layer stack. @@ -548,6 +684,21 @@ public abstract static class Builder { */ public abstract Builder foregroundDrawable(@DrawableRes int foregroundDrawable); + /** + * Given a String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_foregroundDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @param foregroundName String icon or maki-icon name + * @return this builder for chaining options together + * @since 0.6.0 + */ + public abstract Builder foregroundName(@Nullable String foregroundName); + /** * Defines the drawable used for the background state icon. * @@ -558,6 +709,21 @@ public abstract static class Builder { */ public abstract Builder backgroundDrawable(@DrawableRes int backgroundDrawable); + /** + * Given a String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_backgroundDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @param backgroundName String icon or maki-icon name + * @return this builder for chaining options together + * @since 0.6.0 + */ + public abstract Builder backgroundName(@Nullable String backgroundName); + /** * Defines the drawable used for the bearing icon. * @@ -568,6 +734,21 @@ public abstract static class Builder { */ public abstract Builder bearingDrawable(@DrawableRes int bearingDrawable); + /** + * Given a String image name, identical to one used in + * the first parameter of {@link com.mapbox.mapboxsdk.maps.MapboxMap#addImage(String, Bitmap)}, the + * plugin, will used this image in place of the provided or default mapbox_bearingDrawable. + *

+ * A maki-icon name (example: "circle-15") may also be provided. These are images that can be loaded + * with certain styles. Note, this will fail if the provided icon name is not provided by the loaded map style. + *

+ * + * @param bearingName String icon or maki-icon name + * @return this builder for chaining options together + * @since 0.6.0 + */ + public abstract Builder bearingName(@Nullable String bearingName); + /** * Defines the bearing icon color as an integer. * diff --git a/plugin-locationlayer/src/main/res/values/attrs.xml b/plugin-locationlayer/src/main/res/values/attrs.xml index 12d48317f..f3267ec37 100644 --- a/plugin-locationlayer/src/main/res/values/attrs.xml +++ b/plugin-locationlayer/src/main/res/values/attrs.xml @@ -8,7 +8,7 @@ - + diff --git a/plugin-locationlayer/src/main/res/values/styles.xml b/plugin-locationlayer/src/main/res/values/styles.xml index 260190a36..40bf1540a 100644 --- a/plugin-locationlayer/src/main/res/values/styles.xml +++ b/plugin-locationlayer/src/main/res/values/styles.xml @@ -5,7 +5,7 @@ @drawable/mapbox_user_icon @drawable/mapbox_user_stroke_icon @drawable/mapbox_user_bearing_icon - @drawable/mapbox_user_puck_icon + @drawable/mapbox_user_puck_icon @drawable/mapbox_user_icon_stale @drawable/mapbox_user_stroke_icon From 6b88e8fba6cca028793f2822a15a15e68dae5c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Mon, 9 Jul 2018 16:26:34 +0200 Subject: [PATCH 2/2] [LLP] custom icons IDs kept in feature's properties --- .../locationlayer/LocationLayerPluginTest.kt | 101 ++++++++++--- .../plugins/utils/MapboxTestingUtils.kt | 8 + .../plugins/locationlayer/LocationLayer.java | 138 ++++++++++-------- .../locationlayer/LocationLayerConstants.java | 5 + 4 files changed, 169 insertions(+), 83 deletions(-) diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt index 1c1c570a5..c11012bb4 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerPluginTest.kt @@ -19,7 +19,6 @@ import android.support.test.runner.AndroidJUnit4 import android.support.v4.content.ContextCompat import com.mapbox.geojson.Point import com.mapbox.mapboxsdk.constants.Style -import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.maps.MapView import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.maps.SupportMapFragment @@ -32,9 +31,7 @@ import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourc import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY import com.mapbox.mapboxsdk.style.layers.PropertyFactory -import com.mapbox.mapboxsdk.style.layers.SymbolLayer import com.mapbox.mapboxsdk.style.sources.GeoJsonSource -import junit.framework.Assert.assertTrue import org.hamcrest.CoreMatchers.* import org.junit.After import org.junit.Assert.assertEquals @@ -157,9 +154,7 @@ class LocationLayerPluginTest { uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) // Check if the puck is visible - val latLng = LatLng(location.latitude, location.longitude) - val point = mapboxMap.projection.toScreenLocation(latLng) - assertThat(mapboxMap.queryRenderedFeatures(point, FOREGROUND_LAYER).isEmpty(), `is`(false)) + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) } } executePluginTest(pluginAction) @@ -202,19 +197,33 @@ class LocationLayerPluginTest { uiController: UiController, context: Context) { val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) + mapboxMap.addImageFromDrawable("custom-background-bitmap", foregroundDrawable) + mapboxMap.addImageFromDrawable("custom-foreground-stale-bitmap", foregroundDrawable) + mapboxMap.addImageFromDrawable("custom-background-stale-bitmap", foregroundDrawable) + mapboxMap.addImageFromDrawable("custom-bearing-bitmap", foregroundDrawable) - val foregroundLayer = mapboxMap.getLayer(FOREGROUND_LAYER) as SymbolLayer - val iconImageValue = foregroundLayer.iconImage.expression.toString() - - assertTrue(iconImageValue.contains("custom-foreground-bitmap")) + plugin.forceLocationUpdate(location) + uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY) + assertThat(mapboxMap.queryRenderedFeatures(location, FOREGROUND_LAYER).isEmpty(), `is`(false)) + + val feature = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0] + assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_ICON), `is`(equalTo("custom-foreground-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_ICON), `is`(equalTo("custom-background-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_FOREGROUND_STALE_ICON), `is`(equalTo("custom-foreground-stale-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BACKGROUND_STALE_ICON), `is`(equalTo("custom-background-stale-bitmap"))) + assertThat(feature.getStringProperty(PROPERTY_BEARING_ICON), `is`(equalTo("custom-bearing-bitmap"))) } } val options = LocationLayerOptions.builder(fragment.activity) - .foregroundName("custom-foreground-bitmap") - .build() + .foregroundName("custom-foreground-bitmap") + .backgroundName("custom-background-bitmap") + .foregroundStaleName("custom-foreground-stale-bitmap") + .backgroundStaleName("custom-background-stale-bitmap") + .bearingName("custom-bearing-bitmap") + .build() executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) } @Test @@ -223,23 +232,75 @@ class LocationLayerPluginTest { override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, uiController: UiController, context: Context) { plugin.renderMode = RenderMode.GPS + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) val foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_media_play) mapboxMap.addImageFromDrawable("custom-foreground-bitmap", foregroundDrawable!!) mapboxMap.addImageFromDrawable("custom-gps-bitmap", foregroundDrawable) - val foregroundLayer = mapboxMap.getLayer(FOREGROUND_LAYER) as SymbolLayer - val iconImageValue = foregroundLayer.iconImage.expression.toString() + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + } + } - assertTrue(iconImageValue.contains("custom-gps-bitmap")) + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_customIconNameRevertsToDefault() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + + plugin.applyStyle(LocationLayerOptions.builder(fragment.activity).build()) + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) + } + } + + val options = LocationLayerOptions.builder(fragment.activity) + .foregroundName("custom-foreground-bitmap") + .gpsName("custom-gps-bitmap") + .build() + executePluginTest(pluginAction, + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) + } + + @Test + fun locationLayerOptions_customGpsIconNameChangeBackWithMode() { + val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction { + override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap, + uiController: UiController, context: Context) { + plugin.renderMode = RenderMode.GPS + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val foregroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(foregroundId, `is`(equalTo("custom-gps-bitmap"))) + + plugin.renderMode = RenderMode.NORMAL + uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY) + + val revertedForegroundId = mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getStringProperty(PROPERTY_FOREGROUND_ICON) + assertThat(revertedForegroundId, `is`(equalTo(FOREGROUND_ICON))) } } val options = LocationLayerOptions.builder(fragment.activity) - .foregroundName("custom-foreground-bitmap") - .gpsName("custom-gps-bitmap") - .build() + .gpsName("custom-gps-bitmap") + .build() executePluginTest(pluginAction, - PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) + PluginGenerationUtil.getLocationLayerPluginProvider(rule.activity, false, null, options)) } @Test diff --git a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt index a44c37a1e..b65cb3278 100644 --- a/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt +++ b/app/src/androidTest/java/com/mapbox/mapboxsdk/plugins/utils/MapboxTestingUtils.kt @@ -4,9 +4,11 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable +import android.location.Location import android.os.Handler import android.os.Looper import com.mapbox.geojson.Feature +import com.mapbox.mapboxsdk.geometry.LatLng import com.mapbox.mapboxsdk.maps.MapboxMap import com.mapbox.mapboxsdk.style.layers.Property import com.mapbox.mapboxsdk.style.sources.GeoJsonSource @@ -15,6 +17,12 @@ fun MapboxMap.querySourceFeatures(sourceId: String): List { return this.getSourceAs(sourceId)?.querySourceFeatures(null) as List } +fun MapboxMap.queryRenderedFeatures(location: Location, layerId: String): List { + val latLng = LatLng(location.latitude, location.longitude) + val point = this.projection.toScreenLocation(latLng) + return this.queryRenderedFeatures(point, layerId) +} + fun MapboxMap.isLayerVisible(layerId: String): Boolean { return this.getLayer(layerId)?.visibility?.value?.equals(Property.VISIBLE)!! } 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 35881c6ae..1fcc3d04d 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 @@ -41,8 +41,13 @@ 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_BACKGROUND_ICON; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_BACKGROUND_STALE_ICON; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_BEARING_ICON; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_COMPASS_BEARING; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_FOREGROUND_ICON; import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_FOREGROUND_ICON_OFFSET; +import static com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.PROPERTY_FOREGROUND_STALE_ICON; 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; @@ -103,7 +108,7 @@ final class LocationLayer implements LocationLayerAnimator.OnLayerAnimationsValu void initializeComponents(LocationLayerOptions options) { addLocationSource(); - addLayers(options); + addLayers(); applyStyle(options); if (isHidden) { @@ -126,6 +131,7 @@ void applyStyle(@NonNull LocationLayerOptions options) { styleBearing(options); styleAccuracy(options.accuracyAlpha(), options.accuracyColor()); styleScaling(options); + determineIconsSource(options); } void setRenderMode(@RenderMode.Mode int renderMode) { @@ -160,6 +166,8 @@ void setRenderMode(@RenderMode.Mode int renderMode) { default: break; } + + determineIconsSource(options); } int getRenderMode() { @@ -192,22 +200,15 @@ private void setLayerVisibility(String layerId, boolean visible) { } } - private void addLayers(LocationLayerOptions options) { - addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER, options); - addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER, options); - addSymbolLayer(FOREGROUND_LAYER, null, options); - addSymbolLayer(BEARING_LAYER, null, options); + private void addLayers() { + addSymbolLayer(SHADOW_LAYER, BACKGROUND_LAYER); + addSymbolLayer(BACKGROUND_LAYER, FOREGROUND_LAYER); + addSymbolLayer(FOREGROUND_LAYER, null); + addSymbolLayer(BEARING_LAYER, null); addAccuracyLayer(); } - private void addSymbolLayer(String layerId, String beforeLayerId, LocationLayerOptions options) { - String foregroundString = options.gpsName() != null ? options.gpsName() : options.foregroundName(); - String foregroundIconString = buildIconString(foregroundString, FOREGROUND_ICON); - String foregroundStaleIconString = buildIconString(options.foregroundStaleName(), FOREGROUND_STALE_ICON); - String backgroundIconString = buildIconString(options.backgroundName(), BACKGROUND_ICON); - String backgroundStaleIconString = buildIconString(options.backgroundStaleName(), BACKGROUND_STALE_ICON); - String bearingIconString = buildIconString(options.bearingName(), BEARING_ICON); - + private void addSymbolLayer(String layerId, String beforeLayerId) { SymbolLayer layer = new SymbolLayer(layerId, LOCATION_SOURCE); layer.setProperties( iconAllowOverlap(true), @@ -224,13 +225,13 @@ private void addSymbolLayer(String layerId, String beforeLayerId, LocationLayerO iconImage( match(literal(layerId), literal(""), stop(FOREGROUND_LAYER, switchCase( - get(PROPERTY_LOCATION_STALE), literal(foregroundStaleIconString), - literal(foregroundIconString))), + get(PROPERTY_LOCATION_STALE), get(PROPERTY_FOREGROUND_STALE_ICON), + get(PROPERTY_FOREGROUND_ICON))), stop(BACKGROUND_LAYER, switchCase( - get(PROPERTY_LOCATION_STALE), literal(backgroundStaleIconString), - literal(backgroundIconString))), + get(PROPERTY_LOCATION_STALE), get(PROPERTY_BACKGROUND_STALE_ICON), + get(PROPERTY_BACKGROUND_ICON))), stop(SHADOW_LAYER, literal(SHADOW_ICON)), - stop(BEARING_LAYER, literal(bearingIconString)) + stop(BEARING_LAYER, get(PROPERTY_BEARING_ICON)) ) ), iconOffset( @@ -264,13 +265,6 @@ private void addLayerToMap(Layer layer, @Nullable String idBelowLayer) { layerMap.add(layer.getId()); } - private String buildIconString(String bitmapName, @NonNull String drawableName) { - if (bitmapName != null) { - return bitmapName; - } - return drawableName; - } - private void setBearingProperty(String propertyId, float bearing) { locationFeature.addNumberProperty(propertyId, bearing); refreshSource(); @@ -348,45 +342,14 @@ private void setLocationPoint(Point locationPoint) { // Styling // - private void styleForeground(@NonNull LocationLayerOptions options) { - boolean isGpsRenderMode = renderMode == RenderMode.GPS; - // GPS name will cover both foreground & foreground stale - if (isGpsRenderMode && options.gpsName() != null) { - return; - } - - if (options.foregroundName() == null) { - int foregroundDrawableResId = isGpsRenderMode ? options.gpsDrawable() : options.foregroundDrawable(); - Drawable foregroundDrawable = getDrawable( - context, foregroundDrawableResId, options.foregroundTintColor()); - mapboxMap.addImage(FOREGROUND_ICON, getBitmapFromDrawable(foregroundDrawable)); - } - if (options.foregroundStaleName() == null) { - int foregroundDrawableResId = isGpsRenderMode ? options.gpsDrawable() : options.foregroundDrawableStale(); - Drawable foregroundDrawableStale = getDrawable( - context, foregroundDrawableResId, options.foregroundStaleTintColor()); - mapboxMap.addImage(FOREGROUND_STALE_ICON, getBitmapFromDrawable(foregroundDrawableStale)); - } - } - private void styleBackground(LocationLayerOptions options) { - if (options.backgroundName() == null) { - Drawable backgroundDrawable = - getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()); - mapboxMap.addImage(BACKGROUND_ICON, getBitmapFromDrawable(backgroundDrawable)); - } - if (options.backgroundStaleName() == null) { - Drawable backgroundDrawableStale = - getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()); - mapboxMap.addImage(BACKGROUND_STALE_ICON, getBitmapFromDrawable(backgroundDrawableStale)); - } - } + Drawable backgroundDrawable = + getDrawable(context, options.backgroundDrawable(), options.backgroundTintColor()); + Drawable backgroundDrawableStale = + getDrawable(context, options.backgroundDrawableStale(), options.backgroundStaleTintColor()); - private void styleBearing(LocationLayerOptions options) { - if (options.bearingName() == null) { - Drawable bearingDrawable = getDrawable(context, options.bearingDrawable(), options.bearingTintColor()); - mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable)); - } + mapboxMap.addImage(BACKGROUND_ICON, getBitmapFromDrawable(backgroundDrawable)); + mapboxMap.addImage(BACKGROUND_STALE_ICON, getBitmapFromDrawable(backgroundDrawableStale)); } private void styleShadow(LocationLayerOptions options) { @@ -394,12 +357,38 @@ private void styleShadow(LocationLayerOptions options) { mapboxMap.addImage(SHADOW_ICON, generateShadow(shadowDrawable, options.elevation())); } + private void styleBearing(LocationLayerOptions options) { + Drawable bearingDrawable = getDrawable(context, options.bearingDrawable(), options.bearingTintColor()); + mapboxMap.addImage(BEARING_ICON, getBitmapFromDrawable(bearingDrawable)); + } + private void styleAccuracy(float accuracyAlpha, @ColorInt int accuracyColor) { locationFeature.addNumberProperty(PROPERTY_ACCURACY_ALPHA, accuracyAlpha); locationFeature.addStringProperty(PROPERTY_ACCURACY_COLOR, colorToRgbaString(accuracyColor)); refreshSource(); } + private void styleForeground(Drawable foregroundDrawable, Drawable foregroundDrawableStale) { + mapboxMap.addImage(FOREGROUND_ICON, getBitmapFromDrawable(foregroundDrawable)); + mapboxMap.addImage(FOREGROUND_STALE_ICON, getBitmapFromDrawable(foregroundDrawableStale)); + } + + private void styleForeground(@NonNull LocationLayerOptions options) { + if (renderMode == RenderMode.GPS) { + styleForegroundGPS(options); + } else { + styleForeground( + getDrawable(context, options.foregroundDrawable(), options.foregroundTintColor()), + getDrawable(context, options.foregroundDrawableStale(), options.foregroundStaleTintColor())); + } + } + + private void styleForegroundGPS(LocationLayerOptions options) { + styleForeground( + getDrawable(context, options.gpsDrawable(), options.foregroundTintColor()), + getDrawable(context, options.gpsDrawable(), options.foregroundStaleTintColor())); + } + private void styleScaling(LocationLayerOptions options) { for (String layerId : layerMap) { Layer layer = mapboxMap.getLayer(layerId); @@ -416,6 +405,29 @@ private void styleScaling(LocationLayerOptions options) { } } + private void determineIconsSource(LocationLayerOptions options) { + String foregroundIconString = buildIconString( + renderMode == RenderMode.GPS ? options.gpsName() : options.foregroundName(), FOREGROUND_ICON); + String foregroundStaleIconString = buildIconString(options.foregroundStaleName(), FOREGROUND_STALE_ICON); + String backgroundIconString = buildIconString(options.backgroundName(), BACKGROUND_ICON); + String backgroundStaleIconString = buildIconString(options.backgroundStaleName(), BACKGROUND_STALE_ICON); + String bearingIconString = buildIconString(options.bearingName(), BEARING_ICON); + + locationFeature.addStringProperty(PROPERTY_FOREGROUND_ICON, foregroundIconString); + locationFeature.addStringProperty(PROPERTY_BACKGROUND_ICON, backgroundIconString); + locationFeature.addStringProperty(PROPERTY_FOREGROUND_STALE_ICON, foregroundStaleIconString); + locationFeature.addStringProperty(PROPERTY_BACKGROUND_STALE_ICON, backgroundStaleIconString); + locationFeature.addStringProperty(PROPERTY_BEARING_ICON, bearingIconString); + refreshSource(); + } + + private String buildIconString(@Nullable String bitmapName, @NonNull String drawableName) { + if (bitmapName != null) { + return bitmapName; + } + return drawableName; + } + void setLocationsStale(boolean isStale) { // If options has stale state disabled, just return here. if (!options.enableStaleState()) { 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 71a5fc398..c3890cbc0 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,6 +26,11 @@ final class LocationLayerConstants { 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"; + static final String PROPERTY_FOREGROUND_ICON = "mapbox-property-foreground-icon"; + static final String PROPERTY_BACKGROUND_ICON = "mapbox-property-background-icon"; + static final String PROPERTY_FOREGROUND_STALE_ICON = "mapbox-property-foreground-stale-icon"; + static final String PROPERTY_BACKGROUND_STALE_ICON = "mapbox-property-background-stale-icon"; + static final String PROPERTY_BEARING_ICON = "mapbox-property-shadow-icon"; // Layers static final String SHADOW_LAYER = "mapbox-location-shadow";