From f1ac3f29c3f1255299db6cf19f7a28d66014593d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Thu, 14 Mar 2019 18:37:54 +0100 Subject: [android] text-color option for formatted sections --- .../activity/style/SymbolLayerActivity.java | 200 +++++++++++++-------- 1 file changed, 129 insertions(+), 71 deletions(-) (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java') diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java index e6bcbe2bfc..244101746b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java @@ -3,13 +3,13 @@ package com.mapbox.mapboxsdk.testapp.activity.style; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.PointF; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; import android.view.ViewGroup; + import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import com.mapbox.geojson.Feature; @@ -22,25 +22,28 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.maps.Style; +import com.mapbox.mapboxsdk.style.expressions.Expression; import com.mapbox.mapboxsdk.style.layers.Property; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.utils.BitmapUtils; +import java.util.Arrays; import java.util.List; import java.util.Objects; +import java.util.Random; import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatFontScale; +import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatTextColor; import static com.mapbox.mapboxsdk.style.expressions.Expression.FormatOption.formatTextFont; import static com.mapbox.mapboxsdk.style.expressions.Expression.concat; import static com.mapbox.mapboxsdk.style.expressions.Expression.format; import static com.mapbox.mapboxsdk.style.expressions.Expression.formatEntry; import static com.mapbox.mapboxsdk.style.expressions.Expression.get; -import static com.mapbox.mapboxsdk.style.expressions.Expression.id; 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.rgb; import static com.mapbox.mapboxsdk.style.expressions.Expression.switchCase; import static com.mapbox.mapboxsdk.style.expressions.Expression.toBool; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap; @@ -48,7 +51,6 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAnchor; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage; -import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOpacity; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAnchor; @@ -56,6 +58,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textFont; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textRotationAlignment; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize; /** @@ -68,18 +71,42 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. private static final String MARKER_SOURCE = "marker-source"; private static final String MARKER_LAYER = "marker-layer"; - private static final String MARKER_ICON = "my-layers-image"; - public static final String ID_FEATURE_PROPERTY = "id"; - public static final String SELECTED_FEATURE_PROPERTY = "selected"; - public static final String TITLE_FEATURE_PROPERTY = "title"; + private static final String ID_FEATURE_PROPERTY = "id"; + private static final String SELECTED_FEATURE_PROPERTY = "selected"; + private static final String TITLE_FEATURE_PROPERTY = "title"; + + private static final String[] NORMAL_FONT_STACK = new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}; + private static final String[] BOLD_FONT_STACK = new String[] {"DIN Offc Pro Bold", "Arial Unicode MS Regular"}; + + private static final String MAPBOX_SIGN_SOURCE = "mapbox-sign-source"; + private static final String MAPBOX_SIGN_LAYER = "mapbox-sign-layer"; + + private static final Expression TEXT_FIELD_EXPRESSION = + switchCase(toBool(get(SELECTED_FEATURE_PROPERTY)), + format( + formatEntry( + get(TITLE_FEATURE_PROPERTY), + formatTextFont(BOLD_FONT_STACK) + ), + formatEntry("\nis fun!", formatFontScale(0.75)) + ), + format( + formatEntry("This is", formatFontScale(0.75)), + formatEntry( + concat(literal("\n"), get(TITLE_FEATURE_PROPERTY)), + formatFontScale(1.25), + formatTextFont(BOLD_FONT_STACK) + ) + ) + ); - private GeoJsonSource geoJsonSource; + private final Random random = new Random(); + private GeoJsonSource markerSource; private FeatureCollection markerCollection; - private SymbolLayer symbolLayer; + private SymbolLayer markerSymbolLayer; + private SymbolLayer mapboxSignSymbolLayer; private MapboxMap mapboxMap; private MapView mapView; - private boolean initialFont; - private boolean styleLoaded; @Override public void onCreate(Bundle savedInstanceState) { @@ -104,50 +131,47 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. @Override public void onMapReady(@NonNull MapboxMap mapboxMap) { this.mapboxMap = mapboxMap; - // image - Drawable icLayersDrawable = getResources().getDrawable(R.drawable.ic_layers); - Bitmap icLayersBitmap = BitmapUtils.getBitmapFromDrawable(icLayersDrawable); + // marker image + Bitmap androidBitmap = BitmapUtils.getBitmapFromDrawable(getResources().getDrawable(R.drawable.ic_android_2)); + Bitmap carBitmap = BitmapUtils.getBitmapFromDrawable( + getResources().getDrawable(R.drawable.ic_directions_car_black)); - // source + // marker source markerCollection = FeatureCollection.fromFeatures(new Feature[] { - Feature.fromGeometry(Point.fromLngLat(4.91638, 52.35673), featureProperties("1", "Marker 1")), - Feature.fromGeometry(Point.fromLngLat(4.91638, 52.34673), featureProperties("2", "Marker 2")) + Feature.fromGeometry(Point.fromLngLat(4.91638, 52.35673), featureProperties("1", "Android")), + Feature.fromGeometry(Point.fromLngLat(4.91638, 52.34673), featureProperties("2", "Car")) }); - geoJsonSource = new GeoJsonSource(MARKER_SOURCE, markerCollection); + markerSource = new GeoJsonSource(MARKER_SOURCE, markerCollection); - // layer - symbolLayer = new SymbolLayer(MARKER_LAYER, MARKER_SOURCE) + // marker layer + markerSymbolLayer = new SymbolLayer(MARKER_LAYER, MARKER_SOURCE) .withProperties( - iconImage(MARKER_ICON), + iconImage(get(TITLE_FEATURE_PROPERTY)), iconIgnorePlacement(true), iconAllowOverlap(true), - iconSize(switchCase(toBool(get(SELECTED_FEATURE_PROPERTY)), literal(3.0f), literal(1.0f))), + iconSize(switchCase(toBool(get(SELECTED_FEATURE_PROPERTY)), literal(1.5f), literal(1.0f))), iconAnchor(Property.ICON_ANCHOR_BOTTOM), - iconColor(Color.RED), - textField( - format( - formatEntry("this is", formatFontScale(0.75)), - formatEntry( - concat(literal("\n"), get(TITLE_FEATURE_PROPERTY)), - formatFontScale(1.25), - formatTextFont(new String[] {"DIN Offc Pro Bold", "Arial Unicode MS Regular"}) - ) - ) - ), - textFont(new String[] {"DIN Offc Pro Regular", "Arial Unicode MS Regular"}), - textColor(Color.RED), + iconColor(Color.BLUE), + textField(TEXT_FIELD_EXPRESSION), + textFont(NORMAL_FONT_STACK), + textColor(Color.BLUE), textAllowOverlap(true), textIgnorePlacement(true), textAnchor(Property.TEXT_ANCHOR_TOP), textSize(10f) ); + // mapbox sign layer + Source mapboxSignSource = new GeoJsonSource(MAPBOX_SIGN_SOURCE, Point.fromLngLat(4.91638, 52.3510)); + mapboxSignSymbolLayer = new SymbolLayer(MAPBOX_SIGN_LAYER, MAPBOX_SIGN_SOURCE); + shuffleMapboxSign(); + mapboxMap.setStyle(new Style.Builder() - .fromUrl("asset://streets.json") - .withImage(MARKER_ICON, Objects.requireNonNull(icLayersBitmap), true) - .withSource(geoJsonSource) - .withLayer(symbolLayer), - style -> styleLoaded = true + .fromUrl("asset://streets.json") + .withImage("Android", Objects.requireNonNull(androidBitmap), false) + .withImage("Car", Objects.requireNonNull(carBitmap), false) + .withSources(markerSource, mapboxSignSource) + .withLayers(markerSymbolLayer, mapboxSignSymbolLayer) ); // Set a click-listener so we can manipulate the map @@ -158,52 +182,90 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. public boolean onMapClick(@NonNull LatLng point) { // Query which features are clicked PointF screenLoc = mapboxMap.getProjection().toScreenLocation(point); - List features = mapboxMap.queryRenderedFeatures(screenLoc, MARKER_LAYER); - if (!features.isEmpty()) { - for (Feature feature : markerCollection.features()) { - if (feature.getStringProperty(TITLE_FEATURE_PROPERTY) - .equals(features.get(0).getStringProperty(TITLE_FEATURE_PROPERTY))) { + List markerFeatures = mapboxMap.queryRenderedFeatures(screenLoc, MARKER_LAYER); + if (!markerFeatures.isEmpty()) { + for (Feature feature : Objects.requireNonNull(markerCollection.features())) { + if (feature.getStringProperty(ID_FEATURE_PROPERTY) + .equals(markerFeatures.get(0).getStringProperty(ID_FEATURE_PROPERTY))) { // use DDS boolean selected = feature.getBooleanProperty(SELECTED_FEATURE_PROPERTY); feature.addBooleanProperty(SELECTED_FEATURE_PROPERTY, !selected); - - // validate symbol flicker regression for #13407 - symbolLayer.setProperties(iconOpacity(match( - get(ID_FEATURE_PROPERTY), literal(1.0f), - stop(feature.getStringProperty("id"), 0.3f) - ))); } } - geoJsonSource.setGeoJson(markerCollection); - - + markerSource.setGeoJson(markerCollection); + } else { + List mapboxSignFeatures = mapboxMap.queryRenderedFeatures(screenLoc, MAPBOX_SIGN_LAYER); + if (!mapboxSignFeatures.isEmpty()) { + shuffleMapboxSign(); + } } return false; } private void toggleTextSize() { - SymbolLayer layer = mapboxMap.getStyle().getLayerAs(MARKER_LAYER); - layer.setProperties(layer.getTextSize().getValue() > 10 ? textSize(10f) : textSize(20f)); + if (markerSymbolLayer != null) { + Number size = markerSymbolLayer.getTextSize().getValue(); + if (size != null) { + markerSymbolLayer.setProperties((float) size > 10 ? textSize(10f) : textSize(20f)); + } + } } private void toggleTextField() { - SymbolLayer layer = mapboxMap.getStyle().getLayerAs(MARKER_LAYER); - layer.setProperties("{title}".equals(layer.getTextField().getValue()) ? textField("āA") : textField("{title}")); + if (markerSymbolLayer != null) { + if (TEXT_FIELD_EXPRESSION.equals(markerSymbolLayer.getTextField().getExpression())) { + markerSymbolLayer.setProperties(textField("āA")); + } else { + markerSymbolLayer.setProperties(textField(TEXT_FIELD_EXPRESSION)); + } + } } private void toggleTextFont() { - SymbolLayer layer = mapboxMap.getStyle().getLayerAs(MARKER_LAYER); - if (initialFont) { - layer.setProperties(textFont(new String[] {"DIN Offc Pro Bold", "Arial Unicode MS Bold"})); - } else { - layer.setProperties(textFont(new String[] {"DIN Offc Pro Medium", "Arial Unicode MS Regular"})); + if (markerSymbolLayer != null) { + if (Arrays.equals(markerSymbolLayer.getTextFont().getValue(), NORMAL_FONT_STACK)) { + markerSymbolLayer.setProperties(textFont(BOLD_FONT_STACK)); + } else { + markerSymbolLayer.setProperties(textFont(NORMAL_FONT_STACK)); + } } - initialFont = !initialFont; } - private JsonObject featureProperties(String id, String title) { + private void shuffleMapboxSign() { + if (mapboxSignSymbolLayer != null) { + mapboxSignSymbolLayer.setProperties( + textField( + format( + formatEntry("M", formatFontScale(2)), + getRandomColorEntryForString("a"), + getRandomColorEntryForString("p"), + getRandomColorEntryForString("b"), + getRandomColorEntryForString("o"), + getRandomColorEntryForString("x") + ) + ), + textColor(Color.BLACK), + textFont(BOLD_FONT_STACK), + textSize(25f), + textRotationAlignment(Property.TEXT_ROTATION_ALIGNMENT_MAP) + ); + } + } + + private Expression.FormatEntry getRandomColorEntryForString(@NonNull String string) { + return formatEntry(string, + formatTextColor( + rgb( + random.nextInt(256), + random.nextInt(256), + random.nextInt(256) + ) + )); + } + + private JsonObject featureProperties(@NonNull String id, @NonNull String title) { JsonObject object = new JsonObject(); object.add(ID_FEATURE_PROPERTY, new JsonPrimitive(id)); object.add(TITLE_FEATURE_PROPERTY, new JsonPrimitive(title)); @@ -264,10 +326,6 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. @Override public boolean onOptionsItemSelected(MenuItem item) { - if (!styleLoaded) { - return super.onOptionsItemSelected(item); - } - switch (item.getItemId()) { case R.id.action_toggle_text_size: toggleTextSize(); -- cgit v1.2.1