From e03584fca95e30c74aacbdb2e879b0c40b3d9e0d Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 7 Sep 2018 13:36:18 +0200 Subject: [PATCH] [localization] - update plugin to support expressions --- gradle/dependencies.gradle | 2 +- .../localization/LocalizationPlugin.java | 67 ++++++++++++++++--- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 6eb7155f2..626a80d71 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -8,7 +8,7 @@ ext { ] version = [ - mapboxMapSdk : '6.4.0', + mapboxMapSdk : '6.5.0', mapboxJava : '3.2.0', playLocation : '15.0.1', autoValue : '1.5.4', diff --git a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java index 29bf8b2e3..5623c6590 100644 --- a/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java +++ b/plugin-localization/src/main/java/com/mapbox/mapboxsdk/plugins/localization/LocalizationPlugin.java @@ -1,20 +1,23 @@ package com.mapbox.mapboxsdk.plugins.localization; import android.support.annotation.NonNull; - import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.plugins.localization.MapLocale.Languages; +import com.mapbox.mapboxsdk.style.expressions.Expression; import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.layers.PropertyValue; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.style.sources.VectorSource; +import timber.log.Timber; import java.util.List; import java.util.Locale; +import static com.mapbox.mapboxsdk.style.expressions.Expression.raw; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField; /** @@ -27,6 +30,20 @@ */ public final class LocalizationPlugin implements MapView.OnMapChangedListener { + // expression syntax + private static final String EXPRESSION_REGEX = "\\bname_.{2}"; + + // faulty step expression workaround + private static final String STEP_REGEX = "\\[\"zoom\"], "; + private static final String STEP_TEMPLATE = "[\"zoom\"], %s, "; + + // legacy token syntax + private static final String TOKEN_TEMPLATE = "{%s}"; + private static final String TOKEN_REGEX = "[{]((name).*?)[}]"; + private static final String TOKEN_NAME = "{name"; + private static final String TOKEN_ABBR = "{abbr}"; + + // configuration private final MapboxMap mapboxMap; private MapLocale mapLocale; @@ -91,6 +108,7 @@ public void setMapLanguage(@NonNull Locale locale) { setMapLanguage(checkMapLocalNonNull(locale)); } + /** * You can pass in a {@link MapLocale} directly into this method which uses the language defined * in it to represent the language found on the map. @@ -104,13 +122,12 @@ public void setMapLanguage(@NonNull MapLocale mapLocale) { for (Source source : mapboxMap.getSources()) { if (sourceIsFromMapbox(source)) { for (Layer layer : layers) { - if (layerHasAdjustableTextField(layer)) { - String textField = ((SymbolLayer) layer).getTextField().getValue(); - if (textField != null - && (textField.contains("{name") || textField.contains("{abbr}"))) { - textField = textField.replaceAll("[{]((name).*?)[}]", - String.format("{%s}", mapLocale.getMapLanguage())); - layer.setProperties(textField(textField)); + if (layer instanceof SymbolLayer) { + PropertyValue textFieldProperty = ((SymbolLayer) layer).getTextField(); + if (textFieldProperty.isExpression()) { + convertExpression(mapLocale, layer, textFieldProperty); + } else { + convertToken(mapLocale, layer, textFieldProperty); } } } @@ -118,6 +135,27 @@ public void setMapLanguage(@NonNull MapLocale mapLocale) { } } + private void convertToken(@NonNull MapLocale mapLocale, Layer layer, PropertyValue textFieldProperty) { + String text = (String) textFieldProperty.getValue(); + if (text != null && (text.contains(TOKEN_NAME) || text.contains(TOKEN_ABBR))) { + layer.setProperties(textField(text.replaceAll( + TOKEN_REGEX, String.format(TOKEN_TEMPLATE, mapLocale.getMapLanguage()) + ))); + } + } + + private void convertExpression(@NonNull MapLocale mapLocale, Layer layer, PropertyValue textFieldProperty) { + Expression textFieldExpression = textFieldProperty.getExpression(); + if (textFieldExpression != null) { + String text = textFieldExpression.toString().replaceAll(EXPRESSION_REGEX, mapLocale.getMapLanguage()); + if (text.startsWith("[\"step") && textFieldExpression.toArray().length % 2 == 0) { + // got an invalid step expression from core, we need to add an additional name_x into step + text = text.replaceAll(STEP_REGEX, String.format(STEP_TEMPLATE, mapLocale.getMapLanguage())); + } + layer.setProperties(textField(raw(text))); + } + } + /* * Camera bounding box */ @@ -199,8 +237,15 @@ private boolean sourceIsFromMapbox(Source singleSource) { * @return true if the layer has a textField eligible for translation, false if not. */ private boolean layerHasAdjustableTextField(Layer singleLayer) { - return singleLayer instanceof SymbolLayer && (((SymbolLayer) singleLayer).getTextField() != null - && (((SymbolLayer) singleLayer).getTextField().getValue() != null - && !(((SymbolLayer) singleLayer).getTextField().getValue().isEmpty()))); + if (singleLayer instanceof SymbolLayer) { + PropertyValue textField = ((SymbolLayer) singleLayer).getTextField(); + if (textField != null) { + Timber.e("TextField is not null: %s - %s", textField.getValue(), textField.getExpression()); + return true; + } else { + Timber.e("TextField is NULL"); + } + } + return false; } } \ No newline at end of file